/ Hex Artifact Content
Login

Artifact 105a4c0b95e6f8c1d03774f88afbf1397e7cacd52c1a4b24de1118d011d05fdd:


0000: 2f 2a 0a 2a 2a 20 32 30 31 31 2d 30 38 2d 31 34  /*.** 2011-08-14
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 50 41 47 45 20 46 4f 52 4d 41  **.** PAGE FORMA
0180: 54 3a 0a 2a 2a 0a 2a 2a 20 20 20 54 68 65 20 6d  T:.**.**   The m
0190: 61 78 69 6d 75 6d 20 70 61 67 65 20 73 69 7a 65  aximum page size
01a0: 20 69 73 20 36 35 35 33 36 20 62 79 74 65 73 2e   is 65536 bytes.
01b0: 0a 2a 2a 0a 2a 2a 20 20 20 53 69 6e 63 65 20 61  .**.**   Since a
01c0: 6c 6c 20 72 65 63 6f 72 64 73 20 61 72 65 20 65  ll records are e
01d0: 71 75 61 6c 20 74 6f 20 6f 72 20 6c 61 72 67 65  qual to or large
01e0: 72 20 74 68 61 6e 20 32 20 62 79 74 65 73 20 69  r than 2 bytes i
01f0: 6e 20 73 69 7a 65 2c 20 61 6e 64 20 0a 2a 2a 20  n size, and .** 
0200: 20 20 73 6f 6d 65 20 73 70 61 63 65 20 77 69 74    some space wit
0210: 68 69 6e 20 74 68 65 20 70 61 67 65 20 69 73 20  hin the page is 
0220: 63 6f 6e 73 75 6d 65 64 20 62 79 20 74 68 65 20  consumed by the 
0230: 70 61 67 65 20 66 6f 6f 74 65 72 2c 20 74 68 65  page footer, the
0240: 72 65 20 6d 75 73 74 0a 2a 2a 20 20 20 62 65 20  re must.**   be 
0250: 6c 65 73 73 20 74 68 61 6e 20 32 5e 31 35 20 72  less than 2^15 r
0260: 65 63 6f 72 64 73 20 6f 6e 20 65 61 63 68 20 70  ecords on each p
0270: 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 45 61 63  age..**.**   Eac
0280: 68 20 70 61 67 65 20 65 6e 64 73 20 77 69 74 68  h page ends with
0290: 20 61 20 66 6f 6f 74 65 72 20 74 68 61 74 20 64   a footer that d
02a0: 65 73 63 72 69 62 65 73 20 74 68 65 20 70 61 67  escribes the pag
02b0: 65 73 20 63 6f 6e 74 65 6e 74 73 2e 20 54 68 69  es contents. Thi
02c0: 73 0a 2a 2a 20 20 20 66 6f 6f 74 65 72 20 73 65  s.**   footer se
02d0: 72 76 65 73 20 61 73 20 73 69 6d 69 6c 61 72 20  rves as similar 
02e0: 70 75 72 70 6f 73 65 20 74 6f 20 74 68 65 20 70  purpose to the p
02f0: 61 67 65 20 68 65 61 64 65 72 20 69 6e 20 61 6e  age header in an
0300: 20 53 51 4c 69 74 65 20 64 61 74 61 62 61 73 65   SQLite database
0310: 2e 0a 2a 2a 20 20 20 41 20 66 6f 6f 74 65 72 20  ..**   A footer 
0320: 69 73 20 75 73 65 64 20 69 6e 73 74 65 61 64 20  is used instead 
0330: 6f 66 20 61 20 68 65 61 64 65 72 20 62 65 63 61  of a header beca
0340: 75 73 65 20 69 74 20 6d 61 6b 65 73 20 69 74 20  use it makes it 
0350: 65 61 73 69 65 72 20 74 6f 0a 2a 2a 20 20 20 70  easier to.**   p
0360: 6f 70 75 6c 61 74 65 20 61 20 6e 65 77 20 70 61  opulate a new pa
0370: 67 65 20 62 61 73 65 64 20 6f 6e 20 61 20 73 6f  ge based on a so
0380: 72 74 65 64 20 6c 69 73 74 20 6f 66 20 6b 65 79  rted list of key
0390: 2f 76 61 6c 75 65 20 70 61 69 72 73 2e 0a 2a 2a  /value pairs..**
03a0: 0a 2a 2a 20 20 20 54 68 65 20 66 6f 6f 74 65 72  .**   The footer
03b0: 20 63 6f 6e 73 69 73 74 73 20 6f 66 20 74 68 65   consists of the
03c0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 76 61 6c 75 65   following value
03d0: 73 20 28 73 74 61 72 74 69 6e 67 20 61 74 20 74  s (starting at t
03e0: 68 65 20 65 6e 64 20 6f 66 0a 2a 2a 20 20 20 74  he end of.**   t
03f0: 68 65 20 70 61 67 65 20 61 6e 64 20 63 6f 6e 74  he page and cont
0400: 69 6e 75 69 6e 67 20 62 61 63 6b 77 61 72 64 73  inuing backwards
0410: 20 74 6f 77 61 72 64 73 20 74 68 65 20 73 74 61   towards the sta
0420: 72 74 29 2e 20 41 6c 6c 20 76 61 6c 75 65 73 20  rt). All values 
0430: 61 72 65 0a 2a 2a 20 20 20 73 74 6f 72 65 64 20  are.**   stored 
0440: 61 73 20 75 6e 73 69 67 6e 65 64 20 62 69 67 2d  as unsigned big-
0450: 65 6e 64 69 61 6e 20 69 6e 74 65 67 65 72 73 2e  endian integers.
0460: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 4e 75 6d  .**.**     * Num
0470: 62 65 72 20 6f 66 20 72 65 63 6f 72 64 73 20 6f  ber of records o
0480: 6e 20 70 61 67 65 20 28 32 20 62 79 74 65 73 29  n page (2 bytes)
0490: 2e 0a 2a 2a 20 20 20 20 20 2a 20 46 6c 61 67 73  ..**     * Flags
04a0: 20 66 69 65 6c 64 20 28 32 20 62 79 74 65 73 29   field (2 bytes)
04b0: 2e 0a 2a 2a 20 20 20 20 20 2a 20 4c 65 66 74 2d  ..**     * Left-
04c0: 68 61 6e 64 20 70 6f 69 6e 74 65 72 20 76 61 6c  hand pointer val
04d0: 75 65 20 28 38 20 62 79 74 65 73 29 2e 0a 2a 2a  ue (8 bytes)..**
04e0: 20 20 20 20 20 2a 20 54 68 65 20 73 74 61 72 74       * The start
04f0: 69 6e 67 20 6f 66 66 73 65 74 20 6f 66 20 65 61  ing offset of ea
0500: 63 68 20 72 65 63 6f 72 64 20 28 32 20 62 79 74  ch record (2 byt
0510: 65 73 20 70 65 72 20 72 65 63 6f 72 64 29 2e 0a  es per record)..
0520: 2a 2a 0a 2a 2a 20 20 20 52 65 63 6f 72 64 73 20  **.**   Records 
0530: 6d 61 79 20 73 70 61 6e 20 70 61 67 65 73 2e 20  may span pages. 
0540: 55 6e 6c 65 73 73 20 69 74 20 68 61 70 70 65 6e  Unless it happen
0550: 73 20 74 6f 20 62 65 20 61 6e 20 65 78 61 63 74  s to be an exact
0560: 20 66 69 74 2c 20 74 68 65 20 70 61 72 74 0a 2a   fit, the part.*
0570: 2a 20 20 20 6f 66 20 74 68 65 20 66 69 6e 61 6c  *   of the final
0580: 20 72 65 63 6f 72 64 20 74 68 61 74 20 73 74 61   record that sta
0590: 72 74 73 20 6f 6e 20 70 61 67 65 20 58 20 74 68  rts on page X th
05a0: 61 74 20 64 6f 65 73 20 6e 6f 74 20 66 69 74 20  at does not fit 
05b0: 6f 6e 20 70 61 67 65 20 58 0a 2a 2a 20 20 20 69  on page X.**   i
05c0: 73 20 73 74 6f 72 65 64 20 61 74 20 74 68 65 20  s stored at the 
05d0: 73 74 61 72 74 20 6f 66 20 70 61 67 65 20 28 58  start of page (X
05e0: 2b 31 29 2e 20 54 68 69 73 20 6d 65 61 6e 73 20  +1). This means 
05f0: 74 68 65 72 65 20 6d 61 79 20 62 65 20 70 61 67  there may be pag
0600: 65 73 20 77 68 65 72 65 0a 2a 2a 20 20 20 28 4e  es where.**   (N
0610: 3d 3d 30 29 2e 20 41 6e 64 20 6f 6e 20 6d 6f 73  ==0). And on mos
0620: 74 20 70 61 67 65 73 20 74 68 65 20 66 69 72 73  t pages the firs
0630: 74 20 72 65 63 6f 72 64 20 74 68 61 74 20 73 74  t record that st
0640: 61 72 74 73 20 6f 6e 20 74 68 65 20 70 61 67 65  arts on the page
0650: 20 77 69 6c 6c 0a 2a 2a 20 20 20 6e 6f 74 20 73   will.**   not s
0660: 74 61 72 74 20 61 74 20 62 79 74 65 20 6f 66 66  tart at byte off
0670: 73 65 74 20 30 2e 20 46 6f 72 20 65 78 61 6d 70  set 0. For examp
0680: 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 61  le:.**.**      a
0690: 61 61 61 61 20 62 62 62 62 62 20 63 63 63 20 3c  aaaa bbbbb ccc <
06a0: 66 6f 6f 74 65 72 3e 20 20 20 20 63 63 20 65 65  footer>    cc ee
06b0: 65 65 65 20 66 66 66 66 66 20 67 20 3c 66 6f 6f  eee fffff g <foo
06c0: 74 65 72 3e 20 20 20 20 67 67 67 67 2e 2e 2e 2e  ter>    gggg....
06d0: 0a 2a 2a 0a 2a 2a 20 52 45 43 4f 52 44 20 46 4f  .**.** RECORD FO
06e0: 52 4d 41 54 3a 0a 2a 2a 20 0a 2a 2a 20 20 20 54  RMAT:.** .**   T
06f0: 68 65 20 66 69 72 73 74 20 62 79 74 65 20 6f 66  he first byte of
0700: 20 74 68 65 20 72 65 63 6f 72 64 20 69 73 20 61   the record is a
0710: 20 66 6c 61 67 73 20 62 79 74 65 2e 20 49 74 20   flags byte. It 
0720: 69 73 20 61 20 63 6f 6d 62 69 6e 61 74 69 6f 6e  is a combination
0730: 0a 2a 2a 20 20 20 6f 66 20 74 68 65 20 66 6f 6c  .**   of the fol
0740: 6c 6f 77 69 6e 67 20 66 6c 61 67 73 20 28 64 65  lowing flags (de
0750: 66 69 6e 65 64 20 69 6e 20 6c 73 6d 49 6e 74 2e  fined in lsmInt.
0760: 68 29 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20  h):.**.**       
0770: 4c 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45 54 45  LSM_START_DELETE
0780: 0a 2a 2a 20 20 20 20 20 20 20 4c 53 4d 5f 45 4e  .**       LSM_EN
0790: 44 5f 44 45 4c 45 54 45 20 0a 2a 2a 20 20 20 20  D_DELETE .**    
07a0: 20 20 20 4c 53 4d 5f 50 4f 49 4e 54 5f 44 45 4c     LSM_POINT_DEL
07b0: 45 54 45 0a 2a 2a 20 20 20 20 20 20 20 4c 53 4d  ETE.**       LSM
07c0: 5f 49 4e 53 45 52 54 20 20 20 20 0a 2a 2a 20 20  _INSERT    .**  
07d0: 20 20 20 20 20 4c 53 4d 5f 53 45 50 41 52 41 54       LSM_SEPARAT
07e0: 4f 52 0a 2a 2a 20 20 20 20 20 20 20 4c 53 4d 5f  OR.**       LSM_
07f0: 53 59 53 54 45 4d 4b 45 59 0a 2a 2a 0a 2a 2a 20  SYSTEMKEY.**.** 
0800: 20 20 49 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f    Immediately fo
0810: 6c 6c 6f 77 69 6e 67 20 74 68 65 20 74 79 70 65  llowing the type
0820: 20 62 79 74 65 20 69 73 20 61 20 70 6f 69 6e 74   byte is a point
0830: 65 72 20 74 6f 20 74 68 65 20 73 6d 61 6c 6c 65  er to the smalle
0840: 73 74 20 6b 65 79 20 0a 2a 2a 20 20 20 69 6e 20  st key .**   in 
0850: 74 68 65 20 6e 65 78 74 20 66 69 6c 65 20 74 68  the next file th
0860: 61 74 20 69 73 20 6c 61 72 67 65 72 20 74 68 61  at is larger tha
0870: 6e 20 74 68 65 20 6b 65 79 20 69 6e 20 74 68 65  n the key in the
0880: 20 63 75 72 72 65 6e 74 20 72 65 63 6f 72 64 2e   current record.
0890: 20 54 68 65 20 0a 2a 2a 20 20 20 70 6f 69 6e 74   The .**   point
08a0: 65 72 20 69 73 20 65 6e 63 6f 64 65 64 20 61 73  er is encoded as
08b0: 20 61 20 76 61 72 69 6e 74 2e 20 57 68 65 6e 20   a varint. When 
08c0: 61 64 64 65 64 20 74 6f 20 74 68 65 20 33 32 2d  added to the 32-
08d0: 62 69 74 20 70 61 67 65 20 6e 75 6d 62 65 72 20  bit page number 
08e0: 0a 2a 2a 20 20 20 73 74 6f 72 65 64 20 69 6e 20  .**   stored in 
08f0: 74 68 65 20 66 6f 6f 74 65 72 2c 20 69 74 20 69  the footer, it i
0900: 73 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65  s the page numbe
0910: 72 20 6f 66 20 74 68 65 20 70 61 67 65 20 74 68  r of the page th
0920: 61 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 0a  at contains the.
0930: 2a 2a 20 20 20 73 6d 61 6c 6c 65 73 74 20 6b 65  **   smallest ke
0940: 79 20 69 6e 20 74 68 65 20 6e 65 78 74 20 73 6f  y in the next so
0950: 72 74 65 64 20 66 69 6c 65 20 74 68 61 74 20 69  rted file that i
0960: 73 20 6c 61 72 67 65 72 20 74 68 61 6e 20 74 68  s larger than th
0970: 69 73 20 6b 65 79 2e 20 0a 2a 2a 0a 2a 2a 20 20  is key. .**.**  
0980: 20 4e 65 78 74 20 69 73 20 74 68 65 20 6e 75 6d   Next is the num
0990: 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
09a0: 74 68 65 20 6b 65 79 2c 20 65 6e 63 6f 64 65 64  the key, encoded
09b0: 20 61 73 20 61 20 76 61 72 69 6e 74 2e 0a 2a 2a   as a varint..**
09c0: 0a 2a 2a 20 20 20 49 66 20 74 68 65 20 4c 53 4d  .**   If the LSM
09d0: 5f 49 4e 53 45 52 54 20 66 6c 61 67 20 69 73 20  _INSERT flag is 
09e0: 73 65 74 2c 20 74 68 65 20 6e 75 6d 62 65 72 20  set, the number 
09f0: 6f 66 20 62 79 74 65 73 20 69 6e 20 74 68 65 20  of bytes in the 
0a00: 76 61 6c 75 65 2c 20 61 73 0a 2a 2a 20 20 20 61  value, as.**   a
0a10: 20 76 61 72 69 6e 74 2c 20 69 73 20 6e 65 78 74   varint, is next
0a20: 2e 0a 2a 2a 0a 2a 2a 20 20 20 46 69 6e 61 6c 6c  ..**.**   Finall
0a30: 79 2c 20 74 68 65 20 62 6c 6f 62 20 6f 66 20 64  y, the blob of d
0a40: 61 74 61 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74  ata containing t
0a50: 68 65 20 6b 65 79 2c 20 61 6e 64 20 66 6f 72 20  he key, and for 
0a60: 4c 53 4d 5f 49 4e 53 45 52 54 0a 2a 2a 20 20 20  LSM_INSERT.**   
0a70: 72 65 63 6f 72 64 73 2c 20 74 68 65 20 76 61 6c  records, the val
0a80: 75 65 20 61 73 20 77 65 6c 6c 2e 0a 2a 2f 0a 0a  ue as well..*/..
0a90: 23 69 66 6e 64 65 66 20 5f 4c 53 4d 5f 49 4e 54  #ifndef _LSM_INT
0aa0: 5f 48 0a 23 20 69 6e 63 6c 75 64 65 20 22 6c 73  _H.# include "ls
0ab0: 6d 49 6e 74 2e 68 22 0a 23 65 6e 64 69 66 0a 0a  mInt.h".#endif..
0ac0: 23 64 65 66 69 6e 65 20 4c 53 4d 5f 4c 4f 47 5f  #define LSM_LOG_
0ad0: 53 54 52 55 43 54 55 52 45 20 30 0a 23 64 65 66  STRUCTURE 0.#def
0ae0: 69 6e 65 20 4c 53 4d 5f 4c 4f 47 5f 44 41 54 41  ine LSM_LOG_DATA
0af0: 20 20 20 20 20 20 30 0a 0a 2f 2a 0a 2a 2a 20 4d        0../*.** M
0b00: 61 63 72 6f 73 20 74 6f 20 68 65 6c 70 20 64 65  acros to help de
0b10: 63 6f 64 65 20 72 65 63 6f 72 64 20 74 79 70 65  code record type
0b20: 73 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 72 74  s..*/.#define rt
0b30: 54 6f 70 69 63 28 65 54 79 70 65 29 20 20 20 20  Topic(eType)    
0b40: 20 20 20 28 28 65 54 79 70 65 29 20 26 20 4c 53     ((eType) & LS
0b50: 4d 5f 53 59 53 54 45 4d 4b 45 59 29 0a 23 64 65  M_SYSTEMKEY).#de
0b60: 66 69 6e 65 20 72 74 49 73 44 65 6c 65 74 65 28  fine rtIsDelete(
0b70: 65 54 79 70 65 29 20 20 20 20 28 28 28 65 54 79  eType)    (((eTy
0b80: 70 65 29 20 26 20 30 78 30 46 29 3d 3d 4c 53 4d  pe) & 0x0F)==LSM
0b90: 5f 50 4f 49 4e 54 5f 44 45 4c 45 54 45 29 0a 0a  _POINT_DELETE)..
0ba0: 23 64 65 66 69 6e 65 20 72 74 49 73 53 65 70 61  #define rtIsSepa
0bb0: 72 61 74 6f 72 28 65 54 79 70 65 29 20 28 28 28  rator(eType) (((
0bc0: 65 54 79 70 65 29 20 26 20 4c 53 4d 5f 53 45 50  eType) & LSM_SEP
0bd0: 41 52 41 54 4f 52 29 21 3d 30 29 0a 23 64 65 66  ARATOR)!=0).#def
0be0: 69 6e 65 20 72 74 49 73 57 72 69 74 65 28 65 54  ine rtIsWrite(eT
0bf0: 79 70 65 29 20 20 20 20 20 28 28 28 65 54 79 70  ype)     (((eTyp
0c00: 65 29 20 26 20 4c 53 4d 5f 49 4e 53 45 52 54 29  e) & LSM_INSERT)
0c10: 21 3d 30 29 0a 23 64 65 66 69 6e 65 20 72 74 49  !=0).#define rtI
0c20: 73 53 79 73 74 65 6d 28 65 54 79 70 65 29 20 20  sSystem(eType)  
0c30: 20 20 28 28 28 65 54 79 70 65 29 20 26 20 4c 53    (((eType) & LS
0c40: 4d 5f 53 59 53 54 45 4d 4b 45 59 29 21 3d 30 29  M_SYSTEMKEY)!=0)
0c50: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 6f 6c 6c  ../*.** The foll
0c60: 6f 77 69 6e 67 20 6d 61 63 72 6f 73 20 61 72 65  owing macros are
0c70: 20 75 73 65 64 20 74 6f 20 61 63 63 65 73 73 20   used to access 
0c80: 61 20 70 61 67 65 20 66 6f 6f 74 65 72 2e 0a 2a  a page footer..*
0c90: 2f 0a 23 64 65 66 69 6e 65 20 53 45 47 4d 45 4e  /.#define SEGMEN
0ca0: 54 5f 4e 52 45 43 4f 52 44 5f 4f 46 46 53 45 54  T_NRECORD_OFFSET
0cb0: 28 70 67 73 7a 29 20 20 20 20 20 20 20 20 28 28  (pgsz)        ((
0cc0: 70 67 73 7a 29 20 2d 20 32 29 0a 23 64 65 66 69  pgsz) - 2).#defi
0cd0: 6e 65 20 53 45 47 4d 45 4e 54 5f 46 4c 41 47 53  ne SEGMENT_FLAGS
0ce0: 5f 4f 46 46 53 45 54 28 70 67 73 7a 29 20 20 20  _OFFSET(pgsz)   
0cf0: 20 20 20 20 20 20 20 28 28 70 67 73 7a 29 20 2d         ((pgsz) -
0d00: 20 32 20 2d 20 32 29 0a 23 64 65 66 69 6e 65 20   2 - 2).#define 
0d10: 53 45 47 4d 45 4e 54 5f 50 4f 49 4e 54 45 52 5f  SEGMENT_POINTER_
0d20: 4f 46 46 53 45 54 28 70 67 73 7a 29 20 20 20 20  OFFSET(pgsz)    
0d30: 20 20 20 20 28 28 70 67 73 7a 29 20 2d 20 32 20      ((pgsz) - 2 
0d40: 2d 20 32 20 2d 20 38 29 0a 23 64 65 66 69 6e 65  - 2 - 8).#define
0d50: 20 53 45 47 4d 45 4e 54 5f 43 45 4c 4c 50 54 52   SEGMENT_CELLPTR
0d60: 5f 4f 46 46 53 45 54 28 70 67 73 7a 2c 20 69 43  _OFFSET(pgsz, iC
0d70: 65 6c 6c 29 20 28 28 70 67 73 7a 29 20 2d 20 32  ell) ((pgsz) - 2
0d80: 20 2d 20 32 20 2d 20 38 20 2d 20 32 20 2d 20 28   - 2 - 8 - 2 - (
0d90: 69 43 65 6c 6c 29 2a 32 29 0a 0a 23 64 65 66 69  iCell)*2)..#defi
0da0: 6e 65 20 53 45 47 4d 45 4e 54 5f 45 4f 46 28 70  ne SEGMENT_EOF(p
0db0: 67 73 7a 2c 20 6e 45 6e 74 72 79 29 20 53 45 47  gsz, nEntry) SEG
0dc0: 4d 45 4e 54 5f 43 45 4c 4c 50 54 52 5f 4f 46 46  MENT_CELLPTR_OFF
0dd0: 53 45 54 28 70 67 73 7a 2c 20 6e 45 6e 74 72 79  SET(pgsz, nEntry
0de0: 29 0a 0a 23 64 65 66 69 6e 65 20 53 45 47 4d 45  )..#define SEGME
0df0: 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 20 20 20  NT_BTREE_FLAG   
0e00: 20 20 30 78 30 30 30 31 0a 23 64 65 66 69 6e 65    0x0001.#define
0e10: 20 50 47 46 54 52 5f 53 4b 49 50 5f 4e 45 58 54   PGFTR_SKIP_NEXT
0e20: 5f 46 4c 41 47 20 20 20 30 78 30 30 30 32 0a 23  _FLAG   0x0002.#
0e30: 64 65 66 69 6e 65 20 50 47 46 54 52 5f 53 4b 49  define PGFTR_SKI
0e40: 50 5f 54 48 49 53 5f 46 4c 41 47 20 20 20 30 78  P_THIS_FLAG   0x
0e50: 30 30 30 34 0a 0a 0a 23 69 66 6e 64 65 66 20 4c  0004...#ifndef L
0e60: 53 4d 5f 53 45 47 4d 45 4e 54 50 54 52 5f 46 52  SM_SEGMENTPTR_FR
0e70: 45 45 5f 54 48 52 45 53 48 4f 4c 44 0a 23 20 64  EE_THRESHOLD.# d
0e80: 65 66 69 6e 65 20 4c 53 4d 5f 53 45 47 4d 45 4e  efine LSM_SEGMEN
0e90: 54 50 54 52 5f 46 52 45 45 5f 54 48 52 45 53 48  TPTR_FREE_THRESH
0ea0: 4f 4c 44 20 31 30 32 34 0a 23 65 6e 64 69 66 0a  OLD 1024.#endif.
0eb0: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
0ec0: 53 65 67 6d 65 6e 74 50 74 72 20 53 65 67 6d 65  SegmentPtr Segme
0ed0: 6e 74 50 74 72 3b 0a 74 79 70 65 64 65 66 20 73  ntPtr;.typedef s
0ee0: 74 72 75 63 74 20 42 6c 6f 62 20 42 6c 6f 62 3b  truct Blob Blob;
0ef0: 0a 0a 73 74 72 75 63 74 20 42 6c 6f 62 20 7b 0a  ..struct Blob {.
0f00: 20 20 6c 73 6d 5f 65 6e 76 20 2a 70 45 6e 76 3b    lsm_env *pEnv;
0f10: 0a 20 20 76 6f 69 64 20 2a 70 44 61 74 61 3b 0a  .  void *pData;.
0f20: 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a 20 20 69    int nData;.  i
0f30: 6e 74 20 6e 41 6c 6c 6f 63 3b 0a 7d 3b 0a 0a 2f  nt nAlloc;.};../
0f40: 2a 0a 2a 2a 20 41 20 53 65 67 6d 65 6e 74 50 74  *.** A SegmentPt
0f50: 72 20 6f 62 6a 65 63 74 20 6d 61 79 20 62 65 20  r object may be 
0f60: 75 73 65 64 20 66 6f 72 20 6f 6e 65 20 6f 66 20  used for one of 
0f70: 74 77 6f 20 70 75 72 70 6f 73 65 73 3a 0a 2a 2a  two purposes:.**
0f80: 0a 2a 2a 20 20 20 2a 20 54 6f 20 69 74 65 72 61  .**   * To itera
0f90: 74 65 20 61 6e 64 2f 6f 72 20 73 65 65 6b 20 77  te and/or seek w
0fa0: 69 74 68 69 6e 20 61 20 73 69 6e 67 6c 65 20 53  ithin a single S
0fb0: 65 67 6d 65 6e 74 20 28 74 68 65 20 63 6f 6d 62  egment (the comb
0fc0: 69 6e 61 74 69 6f 6e 20 6f 66 20 61 20 0a 2a 2a  ination of a .**
0fd0: 20 20 20 20 20 6d 61 69 6e 20 72 75 6e 20 61 6e       main run an
0fe0: 64 20 61 6e 20 6f 70 74 69 6f 6e 61 6c 20 73 6f  d an optional so
0ff0: 72 74 65 64 20 72 75 6e 29 2e 0a 2a 2a 0a 2a 2a  rted run)..**.**
1000: 20 20 20 2a 20 54 6f 20 69 74 65 72 61 74 65 20     * To iterate 
1010: 74 68 72 6f 75 67 68 20 74 68 65 20 73 65 70 61  through the sepa
1020: 72 61 74 6f 72 73 20 61 72 72 61 79 20 6f 66 20  rators array of 
1030: 61 20 73 65 67 6d 65 6e 74 2e 0a 2a 2f 0a 73 74  a segment..*/.st
1040: 72 75 63 74 20 53 65 67 6d 65 6e 74 50 74 72 20  ruct SegmentPtr 
1050: 7b 0a 20 20 4c 65 76 65 6c 20 2a 70 4c 65 76 65  {.  Level *pLeve
1060: 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l;              
1070: 20 20 2f 2a 20 4c 65 76 65 6c 20 6f 62 6a 65 63    /* Level objec
1080: 74 20 73 65 67 6d 65 6e 74 20 69 73 20 70 61 72  t segment is par
1090: 74 20 6f 66 20 2a 2f 0a 20 20 53 65 67 6d 65 6e  t of */.  Segmen
10a0: 74 20 2a 70 53 65 67 3b 20 20 20 20 20 20 20 20  t *pSeg;        
10b0: 20 20 20 20 20 20 20 20 2f 2a 20 53 65 67 6d 65          /* Segme
10c0: 6e 74 20 74 6f 20 61 63 63 65 73 73 20 2a 2f 0a  nt to access */.
10d0: 0a 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 70 61  .  /* Current pa
10e0: 67 65 2e 20 53 65 65 20 73 65 67 6d 65 6e 74 50  ge. See segmentP
10f0: 74 72 4c 6f 61 64 50 61 67 65 28 29 2e 20 2a 2f  trLoadPage(). */
1100: 0a 20 20 50 61 67 65 20 2a 70 50 67 3b 20 20 20  .  Page *pPg;   
1110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1120: 20 2f 2a 20 43 75 72 72 65 6e 74 20 70 61 67 65   /* Current page
1130: 20 2a 2f 0a 20 20 75 31 36 20 66 6c 61 67 73 3b   */.  u16 flags;
1140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1150: 20 20 20 20 2f 2a 20 43 6f 70 79 20 6f 66 20 70      /* Copy of p
1160: 61 67 65 20 66 6c 61 67 73 20 66 69 65 6c 64 20  age flags field 
1170: 2a 2f 0a 20 20 69 6e 74 20 6e 43 65 6c 6c 3b 20  */.  int nCell; 
1180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1190: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
11a0: 63 65 6c 6c 73 20 6f 6e 20 70 50 67 20 2a 2f 0a  cells on pPg */.
11b0: 20 20 50 67 6e 6f 20 69 50 74 72 3b 20 20 20 20    Pgno iPtr;    
11c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11d0: 2f 2a 20 42 61 73 65 20 63 61 73 63 61 64 65 20  /* Base cascade 
11e0: 70 6f 69 6e 74 65 72 20 2a 2f 0a 0a 20 20 2f 2a  pointer */..  /*
11f0: 20 43 75 72 72 65 6e 74 20 63 65 6c 6c 2e 20 53   Current cell. S
1200: 65 65 20 73 65 67 6d 65 6e 74 50 74 72 4c 6f 61  ee segmentPtrLoa
1210: 64 43 65 6c 6c 28 29 20 2a 2f 0a 20 20 69 6e 74  dCell() */.  int
1220: 20 69 43 65 6c 6c 3b 20 20 20 20 20 20 20 20 20   iCell;         
1230: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
1240: 72 72 65 6e 74 20 72 65 63 6f 72 64 20 77 69 74  rrent record wit
1250: 68 69 6e 20 70 61 67 65 20 70 50 67 20 2a 2f 0a  hin page pPg */.
1260: 20 20 69 6e 74 20 65 54 79 70 65 3b 20 20 20 20    int eType;    
1270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1280: 2f 2a 20 54 79 70 65 20 6f 66 20 63 75 72 72 65  /* Type of curre
1290: 6e 74 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 50  nt record */.  P
12a0: 67 6e 6f 20 69 50 67 50 74 72 3b 20 20 20 20 20  gno iPgPtr;     
12b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12c0: 43 61 73 63 61 64 65 20 70 6f 69 6e 74 65 72 20  Cascade pointer 
12d0: 6f 66 66 73 65 74 20 2a 2f 0a 20 20 76 6f 69 64  offset */.  void
12e0: 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79   *pKey; int nKey
12f0: 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 4b 65 79  ;         /* Key
1300: 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
1310: 20 63 75 72 72 65 6e 74 20 72 65 63 6f 72 64 20   current record 
1320: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 56 61 6c 3b  */.  void *pVal;
1330: 20 69 6e 74 20 6e 56 61 6c 3b 20 20 20 20 20 20   int nVal;      
1340: 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 72 65     /* Current re
1350: 63 6f 72 64 20 76 61 6c 75 65 20 28 65 54 79 70  cord value (eTyp
1360: 65 3d 3d 57 52 49 54 45 20 6f 6e 6c 79 29 20 2a  e==WRITE only) *
1370: 2f 0a 0a 20 20 2f 2a 20 42 6c 6f 62 73 20 75 73  /..  /* Blobs us
1380: 65 64 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 62  ed to allocate b
1390: 75 66 66 65 72 73 20 66 6f 72 20 70 4b 65 79 20  uffers for pKey 
13a0: 61 6e 64 20 70 56 61 6c 20 61 73 20 72 65 71 75  and pVal as requ
13b0: 69 72 65 64 20 2a 2f 0a 20 20 42 6c 6f 62 20 62  ired */.  Blob b
13c0: 6c 6f 62 31 3b 0a 20 20 42 6c 6f 62 20 62 6c 6f  lob1;.  Blob blo
13d0: 62 32 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 55 73  b2;.};../*.** Us
13e0: 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74 68  ed to iterate th
13f0: 72 6f 75 67 68 20 74 68 65 20 6b 65 79 73 20 73  rough the keys s
1400: 74 6f 72 65 64 20 69 6e 20 61 20 62 2d 74 72 65  tored in a b-tre
1410: 65 20 68 69 65 72 61 72 63 68 79 20 66 72 6f 6d  e hierarchy from
1420: 20 73 74 61 72 74 0a 2a 2a 20 74 6f 20 66 69 6e   start.** to fin
1430: 69 73 68 2e 20 4f 6e 6c 79 20 46 69 72 73 74 28  ish. Only First(
1440: 29 20 61 6e 64 20 4e 65 78 74 28 29 20 6f 70 65  ) and Next() ope
1450: 72 61 74 69 6f 6e 73 20 61 72 65 20 72 65 71 75  rations are requ
1460: 69 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 62 74  ired..**.**   bt
1470: 72 65 65 43 75 72 73 6f 72 4e 65 77 28 29 0a 2a  reeCursorNew().*
1480: 2a 20 20 20 62 74 72 65 65 43 75 72 73 6f 72 46  *   btreeCursorF
1490: 69 72 73 74 28 29 0a 2a 2a 20 20 20 62 74 72 65  irst().**   btre
14a0: 65 43 75 72 73 6f 72 4e 65 78 74 28 29 0a 2a 2a  eCursorNext().**
14b0: 20 20 20 62 74 72 65 65 43 75 72 73 6f 72 46 72     btreeCursorFr
14c0: 65 65 28 29 0a 2a 2a 20 20 20 62 74 72 65 65 43  ee().**   btreeC
14d0: 75 72 73 6f 72 50 6f 73 69 74 69 6f 6e 28 29 0a  ursorPosition().
14e0: 2a 2a 20 20 20 62 74 72 65 65 43 75 72 73 6f 72  **   btreeCursor
14f0: 52 65 73 74 6f 72 65 28 29 0a 2a 2f 0a 74 79 70  Restore().*/.typ
1500: 65 64 65 66 20 73 74 72 75 63 74 20 42 74 72 65  edef struct Btre
1510: 65 50 67 20 42 74 72 65 65 50 67 3b 0a 74 79 70  ePg BtreePg;.typ
1520: 65 64 65 66 20 73 74 72 75 63 74 20 42 74 72 65  edef struct Btre
1530: 65 43 75 72 73 6f 72 20 42 74 72 65 65 43 75 72  eCursor BtreeCur
1540: 73 6f 72 3b 0a 73 74 72 75 63 74 20 42 74 72 65  sor;.struct Btre
1550: 65 50 67 20 7b 0a 20 20 50 61 67 65 20 2a 70 50  ePg {.  Page *pP
1560: 61 67 65 3b 0a 20 20 69 6e 74 20 69 43 65 6c 6c  age;.  int iCell
1570: 3b 0a 7d 3b 0a 73 74 72 75 63 74 20 42 74 72 65  ;.};.struct Btre
1580: 65 43 75 72 73 6f 72 20 7b 0a 20 20 53 65 67 6d  eCursor {.  Segm
1590: 65 6e 74 20 2a 70 53 65 67 3b 20 20 20 20 20 20  ent *pSeg;      
15a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
15b0: 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 74  terate through t
15c0: 68 69 73 20 73 65 67 6d 65 6e 74 73 20 62 74 72  his segments btr
15d0: 65 65 20 2a 2f 0a 20 20 46 69 6c 65 53 79 73 74  ee */.  FileSyst
15e0: 65 6d 20 2a 70 46 53 3b 20 20 20 20 20 20 20 20  em *pFS;        
15f0: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20          /* File 
1600: 73 79 73 74 65 6d 20 74 6f 20 72 65 61 64 20 70  system to read p
1610: 61 67 65 73 20 66 72 6f 6d 20 2a 2f 0a 20 20 69  ages from */.  i
1620: 6e 74 20 6e 44 65 70 74 68 3b 20 20 20 20 20 20  nt nDepth;      
1630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1640: 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73 69 7a 65  * Allocated size
1650: 20 6f 66 20 61 50 67 5b 5d 20 2a 2f 0a 20 20 69   of aPg[] */.  i
1660: 6e 74 20 69 50 67 3b 20 20 20 20 20 20 20 20 20  nt iPg;         
1670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1680: 2a 20 43 75 72 72 65 6e 74 20 65 6e 74 72 79 20  * Current entry 
1690: 69 6e 20 61 50 67 5b 5d 2e 20 2d 31 20 2d 3e 20  in aPg[]. -1 -> 
16a0: 45 4f 46 2e 20 2a 2f 0a 20 20 42 74 72 65 65 50  EOF. */.  BtreeP
16b0: 67 20 2a 61 50 67 3b 20 20 20 20 20 20 20 20 20  g *aPg;         
16c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67            /* Pag
16d0: 65 73 20 66 72 6f 6d 20 72 6f 6f 74 20 74 6f 20  es from root to 
16e0: 63 75 72 72 65 6e 74 20 6c 6f 63 61 74 69 6f 6e  current location
16f0: 20 2a 2f 0a 0a 20 20 2f 2a 20 43 61 63 68 65 20   */..  /* Cache 
1700: 6f 66 20 63 75 72 72 65 6e 74 20 65 6e 74 72 79  of current entry
1710: 2e 20 70 4b 65 79 3d 3d 30 20 66 6f 72 20 45 4f  . pKey==0 for EO
1720: 46 2e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 4b  F. */.  void *pK
1730: 65 79 3b 0a 20 20 69 6e 74 20 6e 4b 65 79 3b 0a  ey;.  int nKey;.
1740: 20 20 69 6e 74 20 65 54 79 70 65 3b 0a 20 20 50    int eType;.  P
1750: 67 6e 6f 20 69 50 74 72 3b 0a 0a 20 20 2f 2a 20  gno iPtr;..  /* 
1760: 53 74 6f 72 61 67 65 20 66 6f 72 20 6b 65 79 2c  Storage for key,
1770: 20 69 66 20 6e 6f 74 20 6c 6f 63 61 6c 20 2a 2f   if not local */
1780: 0a 20 20 42 6c 6f 62 20 62 6c 6f 62 3b 0a 7d 3b  .  Blob blob;.};
1790: 0a 0a 0a 2f 2a 0a 2a 2a 20 41 20 63 75 72 73 6f  .../*.** A curso
17a0: 72 20 75 73 65 64 20 66 6f 72 20 6d 65 72 67 65  r used for merge
17b0: 64 20 73 65 61 72 63 68 65 73 20 6f 72 20 69 74  d searches or it
17c0: 65 72 61 74 69 6f 6e 73 20 74 68 72 6f 75 67 68  erations through
17d0: 20 75 70 20 74 6f 20 6f 6e 65 0a 2a 2a 20 54 72   up to one.** Tr
17e0: 65 65 20 73 74 72 75 63 74 75 72 65 20 61 6e 64  ee structure and
17f0: 20 61 6e 79 20 6e 75 6d 62 65 72 20 6f 66 20 73   any number of s
1800: 6f 72 74 65 64 20 66 69 6c 65 73 2e 0a 2a 2a 0a  orted files..**.
1810: 2a 2a 20 20 20 6c 73 6d 4d 43 75 72 73 6f 72 4e  **   lsmMCursorN
1820: 65 77 28 29 0a 2a 2a 20 20 20 6c 73 6d 4d 43 75  ew().**   lsmMCu
1830: 72 73 6f 72 53 65 65 6b 28 29 0a 2a 2a 20 20 20  rsorSeek().**   
1840: 6c 73 6d 4d 43 75 72 73 6f 72 4e 65 78 74 28 29  lsmMCursorNext()
1850: 0a 2a 2a 20 20 20 6c 73 6d 4d 43 75 72 73 6f 72  .**   lsmMCursor
1860: 50 72 65 76 28 29 0a 2a 2a 20 20 20 6c 73 6d 4d  Prev().**   lsmM
1870: 43 75 72 73 6f 72 46 69 72 73 74 28 29 0a 2a 2a  CursorFirst().**
1880: 20 20 20 6c 73 6d 4d 43 75 72 73 6f 72 4c 61 73     lsmMCursorLas
1890: 74 28 29 0a 2a 2a 20 20 20 6c 73 6d 4d 43 75 72  t().**   lsmMCur
18a0: 73 6f 72 4b 65 79 28 29 0a 2a 2a 20 20 20 6c 73  sorKey().**   ls
18b0: 6d 4d 43 75 72 73 6f 72 56 61 6c 75 65 28 29 0a  mMCursorValue().
18c0: 2a 2a 20 20 20 6c 73 6d 4d 43 75 72 73 6f 72 56  **   lsmMCursorV
18d0: 61 6c 69 64 28 29 0a 2a 2a 0a 2a 2a 20 69 46 72  alid().**.** iFr
18e0: 65 65 3a 0a 2a 2a 20 20 20 54 68 69 73 20 76 61  ee:.**   This va
18f0: 72 69 61 62 6c 65 20 69 73 20 6f 6e 6c 79 20 75  riable is only u
1900: 73 65 64 20 62 79 20 63 75 72 73 6f 72 73 20 70  sed by cursors p
1910: 72 6f 76 69 64 69 6e 67 20 69 6e 70 75 74 20 64  roviding input d
1920: 61 74 61 20 66 6f 72 20 61 0a 2a 2a 20 20 20 6e  ata for a.**   n
1930: 65 77 20 74 6f 70 2d 6c 65 76 65 6c 20 73 65 67  ew top-level seg
1940: 6d 65 6e 74 2e 20 53 75 63 68 20 63 75 72 73 6f  ment. Such curso
1950: 72 73 20 6f 6e 6c 79 20 65 76 65 72 20 69 74 65  rs only ever ite
1960: 72 61 74 65 20 66 6f 72 77 61 72 64 73 2c 20 6e  rate forwards, n
1970: 6f 74 0a 2a 2a 20 20 20 62 61 63 6b 77 61 72 64  ot.**   backward
1980: 73 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 4d 75 6c  s..*/.struct Mul
1990: 74 69 43 75 72 73 6f 72 20 7b 0a 20 20 6c 73 6d  tiCursor {.  lsm
19a0: 5f 64 62 20 2a 70 44 62 3b 20 20 20 20 20 20 20  _db *pDb;       
19b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
19c0: 43 6f 6e 6e 65 63 74 69 6f 6e 20 74 68 61 74 20  Connection that 
19d0: 6f 77 6e 73 20 74 68 69 73 20 63 75 72 73 6f 72  owns this cursor
19e0: 20 2a 2f 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f   */.  MultiCurso
19f0: 72 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20  r *pNext;       
1a00: 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 63 75        /* Next cu
1a10: 72 73 6f 72 20 6f 77 6e 65 64 20 62 79 20 63 6f  rsor owned by co
1a20: 6e 6e 65 63 74 69 6f 6e 20 70 44 62 20 2a 2f 0a  nnection pDb */.
1a30: 20 20 69 6e 74 20 66 6c 61 67 73 3b 20 20 20 20    int flags;    
1a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a50: 20 20 2f 2a 20 4d 61 73 6b 20 6f 66 20 43 55 52    /* Mask of CUR
1a60: 53 4f 52 5f 58 58 58 20 66 6c 61 67 73 20 2a 2f  SOR_XXX flags */
1a70: 0a 0a 20 20 69 6e 74 20 65 54 79 70 65 3b 20 20  ..  int eType;  
1a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a90: 20 20 20 20 2f 2a 20 43 61 63 68 65 20 6f 66 20      /* Cache of 
1aa0: 63 75 72 72 65 6e 74 20 6b 65 79 20 74 79 70 65  current key type
1ab0: 20 2a 2f 0a 20 20 42 6c 6f 62 20 6b 65 79 3b 20   */.  Blob key; 
1ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ad0: 20 20 20 20 20 20 2f 2a 20 43 61 63 68 65 20 6f        /* Cache o
1ae0: 66 20 63 75 72 72 65 6e 74 20 6b 65 79 20 28 6f  f current key (o
1af0: 72 20 4e 55 4c 4c 29 20 2a 2f 0a 20 20 42 6c 6f  r NULL) */.  Blo
1b00: 62 20 76 61 6c 3b 20 20 20 20 20 20 20 20 20 20  b val;          
1b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1b20: 43 61 63 68 65 20 6f 66 20 63 75 72 72 65 6e 74  Cache of current
1b30: 20 76 61 6c 75 65 20 2a 2f 0a 0a 20 20 2f 2a 20   value */..  /* 
1b40: 41 6c 6c 20 74 68 65 20 63 6f 6d 70 6f 6e 65 6e  All the componen
1b50: 74 20 63 75 72 73 6f 72 73 3a 20 2a 2f 0a 20 20  t cursors: */.  
1b60: 54 72 65 65 43 75 72 73 6f 72 20 2a 61 70 54 72  TreeCursor *apTr
1b70: 65 65 43 73 72 5b 32 5d 3b 20 20 20 20 20 20 20  eeCsr[2];       
1b80: 2f 2a 20 55 70 20 74 6f 20 74 77 6f 20 74 72 65  /* Up to two tre
1b90: 65 20 63 75 72 73 6f 72 73 20 2a 2f 0a 20 20 69  e cursors */.  i
1ba0: 6e 74 20 69 46 72 65 65 3b 20 20 20 20 20 20 20  nt iFree;       
1bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1bc0: 2a 20 4e 65 78 74 20 65 6c 65 6d 65 6e 74 20 6f  * Next element o
1bd0: 66 20 66 72 65 65 2d 6c 69 73 74 20 28 2d 76 65  f free-list (-ve
1be0: 20 66 6f 72 20 65 6f 66 29 20 2a 2f 0a 20 20 53   for eof) */.  S
1bf0: 65 67 6d 65 6e 74 50 74 72 20 2a 61 50 74 72 3b  egmentPtr *aPtr;
1c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1c10: 2a 20 41 72 72 61 79 20 6f 66 20 73 65 67 6d 65  * Array of segme
1c20: 6e 74 20 70 6f 69 6e 74 65 72 73 20 2a 2f 0a 20  nt pointers */. 
1c30: 20 69 6e 74 20 6e 50 74 72 3b 20 20 20 20 20 20   int nPtr;      
1c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c50: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 72 72 61   /* Size of arra
1c60: 79 20 61 50 74 72 5b 5d 20 2a 2f 0a 20 20 42 74  y aPtr[] */.  Bt
1c70: 72 65 65 43 75 72 73 6f 72 20 2a 70 42 74 43 73  reeCursor *pBtCs
1c80: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  r;            /*
1c90: 20 62 2d 74 72 65 65 20 63 75 72 73 6f 72 20 28   b-tree cursor (
1ca0: 64 62 20 77 72 69 74 65 73 20 6f 6e 6c 79 29 20  db writes only) 
1cb0: 2a 2f 0a 0a 20 20 2f 2a 20 43 6f 6d 70 61 72 69  */..  /* Compari
1cc0: 73 6f 6e 20 72 65 73 75 6c 74 73 20 2a 2f 0a 20  son results */. 
1cd0: 20 69 6e 74 20 6e 54 72 65 65 3b 20 20 20 20 20   int nTree;     
1ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cf0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 54 72 65   /* Size of aTre
1d00: 65 5b 5d 20 61 72 72 61 79 20 2a 2f 0a 20 20 69  e[] array */.  i
1d10: 6e 74 20 2a 61 54 72 65 65 3b 20 20 20 20 20 20  nt *aTree;      
1d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1d30: 2a 20 41 72 72 61 79 20 6f 66 20 63 6f 6d 70 61  * Array of compa
1d40: 72 69 73 6f 6e 20 72 65 73 75 6c 74 73 20 2a 2f  rison results */
1d50: 0a 0a 20 20 2f 2a 20 55 73 65 64 20 62 79 20 63  ..  /* Used by c
1d60: 75 72 73 6f 72 73 20 66 6c 75 73 68 69 6e 67 20  ursors flushing 
1d70: 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 74 72  the in-memory tr
1d80: 65 65 20 6f 6e 6c 79 20 2a 2f 0a 20 20 76 6f 69  ee only */.  voi
1d90: 64 20 2a 70 53 79 73 74 65 6d 56 61 6c 3b 20 20  d *pSystemVal;  
1da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1db0: 50 6f 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65  Pointer to buffe
1dc0: 72 20 74 6f 20 66 72 65 65 20 2a 2f 0a 0a 20 20  r to free */..  
1dd0: 2f 2a 20 55 73 65 64 20 62 79 20 77 6f 72 6b 65  /* Used by worke
1de0: 72 20 63 75 72 73 6f 72 73 20 6f 6e 6c 79 20 2a  r cursors only *
1df0: 2f 0a 20 20 50 67 6e 6f 20 2a 70 50 72 65 76 4d  /.  Pgno *pPrevM
1e00: 65 72 67 65 50 74 72 3b 0a 7d 3b 0a 0a 2f 2a 0a  ergePtr;.};../*.
1e10: 2a 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ** The following
1e20: 20 63 6f 6e 73 74 61 6e 74 73 20 61 72 65 20 75   constants are u
1e30: 73 65 64 20 74 6f 20 61 73 73 69 67 6e 20 69 6e  sed to assign in
1e40: 74 65 67 65 72 73 20 74 6f 20 65 61 63 68 20 63  tegers to each c
1e50: 6f 6d 70 6f 6e 65 6e 74 0a 2a 2a 20 63 75 72 73  omponent.** curs
1e60: 6f 72 20 6f 66 20 61 20 6d 75 6c 74 69 2d 63 75  or of a multi-cu
1e70: 72 73 6f 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  rsor..*/.#define
1e80: 20 43 55 52 53 4f 52 5f 44 41 54 41 5f 54 52 45   CURSOR_DATA_TRE
1e90: 45 30 20 20 20 20 20 30 20 20 20 2f 2a 20 43 75  E0     0   /* Cu
1ea0: 72 72 65 6e 74 20 74 72 65 65 20 63 75 72 73 6f  rrent tree curso
1eb0: 72 20 28 61 70 54 72 65 65 43 73 72 5b 30 5d 29  r (apTreeCsr[0])
1ec0: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 43 55 52 53   */.#define CURS
1ed0: 4f 52 5f 44 41 54 41 5f 54 52 45 45 31 20 20 20  OR_DATA_TREE1   
1ee0: 20 20 31 20 20 20 2f 2a 20 54 68 65 20 22 6f 6c    1   /* The "ol
1ef0: 64 22 20 74 72 65 65 2c 20 69 66 20 61 6e 79 20  d" tree, if any 
1f00: 28 61 70 54 72 65 65 43 73 72 5b 31 5d 29 20 2a  (apTreeCsr[1]) *
1f10: 2f 0a 23 64 65 66 69 6e 65 20 43 55 52 53 4f 52  /.#define CURSOR
1f20: 5f 44 41 54 41 5f 53 59 53 54 45 4d 20 20 20 20  _DATA_SYSTEM    
1f30: 32 20 20 20 2f 2a 20 46 72 65 65 2d 6c 69 73 74  2   /* Free-list
1f40: 20 65 6e 74 72 69 65 73 20 28 6e 65 77 2d 74 6f   entries (new-to
1f50: 70 6c 65 76 65 6c 20 6f 6e 6c 79 29 20 2a 2f 0a  plevel only) */.
1f60: 23 64 65 66 69 6e 65 20 43 55 52 53 4f 52 5f 44  #define CURSOR_D
1f70: 41 54 41 5f 53 45 47 4d 45 4e 54 20 20 20 33 20  ATA_SEGMENT   3 
1f80: 20 20 2f 2a 20 46 69 72 73 74 20 73 65 67 6d 65    /* First segme
1f90: 6e 74 20 70 6f 69 6e 74 65 72 20 28 61 50 74 72  nt pointer (aPtr
1fa0: 5b 30 5d 29 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 43  [0]) */../*.** C
1fb0: 55 52 53 4f 52 5f 49 47 4e 4f 52 45 5f 44 45 4c  URSOR_IGNORE_DEL
1fc0: 45 54 45 0a 2a 2a 20 20 20 49 66 20 73 65 74 2c  ETE.**   If set,
1fd0: 20 74 68 69 73 20 63 75 72 73 6f 72 20 77 69 6c   this cursor wil
1fe0: 6c 20 6e 6f 74 20 76 69 73 69 74 20 53 4f 52 54  l not visit SORT
1ff0: 45 44 5f 44 45 4c 45 54 45 20 6b 65 79 73 2e 0a  ED_DELETE keys..
2000: 2a 2a 0a 2a 2a 20 43 55 52 53 4f 52 5f 46 4c 55  **.** CURSOR_FLU
2010: 53 48 5f 46 52 45 45 4c 49 53 54 0a 2a 2a 20 20  SH_FREELIST.**  
2020: 20 54 68 69 73 20 63 75 72 73 6f 72 20 69 73 20   This cursor is 
2030: 62 65 69 6e 67 20 75 73 65 64 20 74 6f 20 63 72  being used to cr
2040: 65 61 74 65 20 61 20 6e 65 77 20 74 6f 70 6c 65  eate a new tople
2050: 76 65 6c 2e 20 49 74 20 73 68 6f 75 6c 64 20 61  vel. It should a
2060: 6c 73 6f 20 0a 2a 2a 20 20 20 69 74 65 72 61 74  lso .**   iterat
2070: 65 20 74 68 72 6f 75 67 68 20 74 68 65 20 63 6f  e through the co
2080: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 69 6e  ntents of the in
2090: 2d 6d 65 6d 6f 72 79 20 66 72 65 65 20 62 6c 6f  -memory free blo
20a0: 63 6b 20 6c 69 73 74 2e 0a 2a 2a 0a 2a 2a 20 43  ck list..**.** C
20b0: 55 52 53 4f 52 5f 49 47 4e 4f 52 45 5f 53 59 53  URSOR_IGNORE_SYS
20c0: 54 45 4d 0a 2a 2a 20 20 20 49 66 20 73 65 74 2c  TEM.**   If set,
20d0: 20 74 68 69 73 20 63 75 72 73 6f 72 20 69 67 6e   this cursor ign
20e0: 6f 72 65 73 20 73 79 73 74 65 6d 20 6b 65 79 73  ores system keys
20f0: 2e 0a 2a 2a 0a 2a 2a 20 43 55 52 53 4f 52 5f 4e  ..**.** CURSOR_N
2100: 45 58 54 5f 4f 4b 0a 2a 2a 20 20 20 53 65 74 20  EXT_OK.**   Set 
2110: 69 66 20 69 74 20 69 73 20 4f 6b 20 74 6f 20 63  if it is Ok to c
2120: 61 6c 6c 20 6c 73 6d 5f 63 73 72 5f 6e 65 78 74  all lsm_csr_next
2130: 28 29 2e 0a 2a 2a 0a 2a 2a 20 43 55 52 53 4f 52  ()..**.** CURSOR
2140: 5f 50 52 45 56 5f 4f 4b 0a 2a 2a 20 20 20 53 65  _PREV_OK.**   Se
2150: 74 20 69 66 20 69 74 20 69 73 20 4f 6b 20 74 6f  t if it is Ok to
2160: 20 63 61 6c 6c 20 6c 73 6d 5f 63 73 72 5f 70 72   call lsm_csr_pr
2170: 65 76 28 29 2e 0a 2a 2a 0a 2a 2a 20 43 55 52 53  ev()..**.** CURS
2180: 4f 52 5f 52 45 41 44 5f 53 45 50 41 52 41 54 4f  OR_READ_SEPARATO
2190: 52 53 0a 2a 2a 20 20 20 53 65 74 20 69 66 20 74  RS.**   Set if t
21a0: 68 69 73 20 63 75 72 73 6f 72 20 73 68 6f 75 6c  his cursor shoul
21b0: 64 20 76 69 73 69 74 20 74 68 65 20 73 65 70 61  d visit the sepa
21c0: 72 61 74 6f 72 20 6b 65 79 73 20 69 6e 20 73 65  rator keys in se
21d0: 67 6d 65 6e 74 20 0a 2a 2a 20 20 20 61 50 74 72  gment .**   aPtr
21e0: 5b 6e 50 74 72 2d 31 5d 2e 0a 2a 2a 0a 2a 2a 20  [nPtr-1]..**.** 
21f0: 43 55 52 53 4f 52 5f 53 45 45 4b 5f 45 51 0a 2a  CURSOR_SEEK_EQ.*
2200: 2a 20 20 20 43 75 72 73 6f 72 20 68 61 73 20 75  *   Cursor has u
2210: 6e 64 65 72 67 6f 6e 65 20 61 20 73 75 63 63 65  ndergone a succe
2220: 73 73 66 75 6c 20 6c 73 6d 5f 63 73 72 5f 73 65  ssful lsm_csr_se
2230: 65 6b 28 4c 53 4d 5f 53 45 45 4b 5f 45 51 29 20  ek(LSM_SEEK_EQ) 
2240: 6f 70 65 72 61 74 69 6f 6e 2e 0a 2a 2a 20 20 20  operation..**   
2250: 54 68 65 20 6b 65 79 20 61 6e 64 20 76 61 6c 75  The key and valu
2260: 65 20 61 72 65 20 73 74 6f 72 65 64 20 69 6e 20  e are stored in 
2270: 4d 75 6c 74 69 43 75 72 73 6f 72 2e 6b 65 79 20  MultiCursor.key 
2280: 61 6e 64 20 4d 75 6c 74 69 43 75 72 73 6f 72 2e  and MultiCursor.
2290: 76 61 6c 0a 2a 2a 20 20 20 72 65 73 70 65 63 74  val.**   respect
22a0: 69 76 65 6c 79 2e 0a 2a 2f 0a 23 64 65 66 69 6e  ively..*/.#defin
22b0: 65 20 43 55 52 53 4f 52 5f 49 47 4e 4f 52 45 5f  e CURSOR_IGNORE_
22c0: 44 45 4c 45 54 45 20 20 20 20 30 78 30 30 30 30  DELETE    0x0000
22d0: 30 30 30 31 0a 23 64 65 66 69 6e 65 20 43 55 52  0001.#define CUR
22e0: 53 4f 52 5f 46 4c 55 53 48 5f 46 52 45 45 4c 49  SOR_FLUSH_FREELI
22f0: 53 54 20 20 20 30 78 30 30 30 30 30 30 30 32 0a  ST   0x00000002.
2300: 23 64 65 66 69 6e 65 20 43 55 52 53 4f 52 5f 49  #define CURSOR_I
2310: 47 4e 4f 52 45 5f 53 59 53 54 45 4d 20 20 20 20  GNORE_SYSTEM    
2320: 30 78 30 30 30 30 30 30 31 30 0a 23 64 65 66 69  0x00000010.#defi
2330: 6e 65 20 43 55 52 53 4f 52 5f 4e 45 58 54 5f 4f  ne CURSOR_NEXT_O
2340: 4b 20 20 20 20 20 20 20 20 20 20 30 78 30 30 30  K          0x000
2350: 30 30 30 32 30 0a 23 64 65 66 69 6e 65 20 43 55  00020.#define CU
2360: 52 53 4f 52 5f 50 52 45 56 5f 4f 4b 20 20 20 20  RSOR_PREV_OK    
2370: 20 20 20 20 20 20 30 78 30 30 30 30 30 30 34 30        0x00000040
2380: 0a 23 64 65 66 69 6e 65 20 43 55 52 53 4f 52 5f  .#define CURSOR_
2390: 52 45 41 44 5f 53 45 50 41 52 41 54 4f 52 53 20  READ_SEPARATORS 
23a0: 20 30 78 30 30 30 30 30 30 38 30 0a 23 64 65 66   0x00000080.#def
23b0: 69 6e 65 20 43 55 52 53 4f 52 5f 53 45 45 4b 5f  ine CURSOR_SEEK_
23c0: 45 51 20 20 20 20 20 20 20 20 20 20 30 78 30 30  EQ          0x00
23d0: 30 30 30 31 30 30 0a 0a 74 79 70 65 64 65 66 20  000100..typedef 
23e0: 73 74 72 75 63 74 20 4d 65 72 67 65 57 6f 72 6b  struct MergeWork
23f0: 65 72 20 4d 65 72 67 65 57 6f 72 6b 65 72 3b 0a  er MergeWorker;.
2400: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 48  typedef struct H
2410: 69 65 72 61 72 63 68 79 20 48 69 65 72 61 72 63  ierarchy Hierarc
2420: 68 79 3b 0a 0a 73 74 72 75 63 74 20 48 69 65 72  hy;..struct Hier
2430: 61 72 63 68 79 20 7b 0a 20 20 50 61 67 65 20 2a  archy {.  Page *
2440: 2a 61 70 48 69 65 72 3b 0a 20 20 69 6e 74 20 6e  *apHier;.  int n
2450: 48 69 65 72 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  Hier;.};../*.** 
2460: 61 53 61 76 65 3a 0a 2a 2a 20 20 20 57 68 65 6e  aSave:.**   When
2470: 20 6d 65 72 67 65 57 6f 72 6b 65 72 4e 65 78 74   mergeWorkerNext
2480: 50 61 67 65 28 29 20 69 73 20 63 61 6c 6c 65 64  Page() is called
2490: 20 74 6f 20 61 64 76 61 6e 63 65 20 74 6f 20 74   to advance to t
24a0: 68 65 20 6e 65 78 74 20 70 61 67 65 20 69 6e 0a  he next page in.
24b0: 2a 2a 20 20 20 74 68 65 20 6f 75 74 70 75 74 20  **   the output 
24c0: 73 65 67 6d 65 6e 74 2c 20 69 66 20 74 68 65 20  segment, if the 
24d0: 62 53 74 6f 72 65 20 66 6c 61 67 20 66 6f 72 20  bStore flag for 
24e0: 61 6e 20 65 6c 65 6d 65 6e 74 20 6f 66 20 61 53  an element of aS
24f0: 61 76 65 5b 5d 20 69 73 0a 2a 2a 20 20 20 74 72  ave[] is.**   tr
2500: 75 65 2c 20 69 74 20 69 73 20 63 6c 65 61 72 65  ue, it is cleare
2510: 64 20 61 6e 64 20 74 68 65 20 63 6f 72 72 65 73  d and the corres
2520: 70 6f 6e 64 69 6e 67 20 69 50 67 6e 6f 20 76 61  ponding iPgno va
2530: 6c 75 65 20 69 73 20 73 65 74 20 74 6f 20 74 68  lue is set to th
2540: 65 20 0a 2a 2a 20 20 20 70 61 67 65 20 6e 75 6d  e .**   page num
2550: 62 65 72 20 6f 66 20 74 68 65 20 70 61 67 65 20  ber of the page 
2560: 6a 75 73 74 20 63 6f 6d 70 6c 65 74 65 64 2e 0a  just completed..
2570: 2a 2a 0a 2a 2a 20 20 20 61 53 61 76 65 5b 30 5d  **.**   aSave[0]
2580: 20 69 73 20 75 73 65 64 20 74 6f 20 72 65 63 6f   is used to reco
2590: 72 64 20 74 68 65 20 70 6f 69 6e 74 65 72 20 76  rd the pointer v
25a0: 61 6c 75 65 20 74 6f 20 62 65 20 70 75 73 68 65  alue to be pushe
25b0: 64 20 69 6e 74 6f 20 74 68 65 0a 2a 2a 20 20 20  d into the.**   
25c0: 62 2d 74 72 65 65 20 68 69 65 72 61 72 63 68 79  b-tree hierarchy
25d0: 2e 20 61 53 61 76 65 5b 31 5d 20 69 73 20 75 73  . aSave[1] is us
25e0: 65 64 20 74 6f 20 73 61 76 65 20 74 68 65 20 70  ed to save the p
25f0: 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68  age number of th
2600: 65 0a 2a 2a 20 20 20 70 61 67 65 20 63 6f 6e 74  e.**   page cont
2610: 61 69 6e 69 6e 67 20 74 68 65 20 69 6e 64 69 72  aining the indir
2620: 65 63 74 20 6b 65 79 20 6d 6f 73 74 20 72 65 63  ect key most rec
2630: 65 6e 74 6c 79 20 77 72 69 74 74 65 6e 20 74 6f  ently written to
2640: 20 74 68 65 20 62 2d 74 72 65 65 2e 0a 2a 2a 20   the b-tree..** 
2650: 20 20 73 65 65 20 6d 65 72 67 65 57 6f 72 6b 65    see mergeWorke
2660: 72 50 75 73 68 48 69 65 72 61 72 63 68 79 28 29  rPushHierarchy()
2670: 20 66 6f 72 20 64 65 74 61 69 6c 73 2e 0a 2a 2f   for details..*/
2680: 0a 73 74 72 75 63 74 20 4d 65 72 67 65 57 6f 72  .struct MergeWor
2690: 6b 65 72 20 7b 0a 20 20 6c 73 6d 5f 64 62 20 2a  ker {.  lsm_db *
26a0: 70 44 62 3b 20 20 20 20 20 20 20 20 20 20 20 20  pDb;            
26b0: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
26c0: 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20  ase handle */.  
26d0: 4c 65 76 65 6c 20 2a 70 4c 65 76 65 6c 3b 20 20  Level *pLevel;  
26e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26f0: 2f 2a 20 57 6f 72 6b 65 72 20 73 6e 61 70 73 68  /* Worker snapsh
2700: 6f 74 20 4c 65 76 65 6c 20 62 65 69 6e 67 20 6d  ot Level being m
2710: 65 72 67 65 64 20 2a 2f 0a 20 20 4d 75 6c 74 69  erged */.  Multi
2720: 43 75 72 73 6f 72 20 2a 70 43 73 72 3b 20 20 20  Cursor *pCsr;   
2730: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
2740: 72 73 6f 72 20 74 6f 20 72 65 61 64 20 6e 65 77  rsor to read new
2750: 20 73 65 67 6d 65 6e 74 20 63 6f 6e 74 65 6e 74   segment content
2760: 73 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e 74 20  s from */.  int 
2770: 62 46 6c 75 73 68 3b 20 20 20 20 20 20 20 20 20  bFlush;         
2780: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
2790: 72 75 65 20 69 66 20 74 68 69 73 20 69 73 20 61  rue if this is a
27a0: 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20 74 72 65 65  n in-memory tree
27b0: 20 66 6c 75 73 68 20 2a 2f 0a 20 20 48 69 65 72   flush */.  Hier
27c0: 61 72 63 68 79 20 68 69 65 72 3b 20 20 20 20 20  archy hier;     
27d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
27e0: 2d 74 72 65 65 20 68 69 65 72 61 72 63 68 79 20  -tree hierarchy 
27f0: 75 6e 64 65 72 20 63 6f 6e 73 74 72 75 63 74 69  under constructi
2800: 6f 6e 20 2a 2f 0a 20 20 50 61 67 65 20 2a 70 50  on */.  Page *pP
2810: 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  age;            
2820: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65          /* Curre
2830: 6e 74 20 6f 75 74 70 75 74 20 70 61 67 65 20 2a  nt output page *
2840: 2f 0a 20 20 69 6e 74 20 6e 57 6f 72 6b 3b 20 20  /.  int nWork;  
2850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2860: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
2870: 20 63 61 6c 6c 73 20 74 6f 20 6d 65 72 67 65 57   calls to mergeW
2880: 6f 72 6b 65 72 4e 65 78 74 50 61 67 65 28 29 20  orkerNextPage() 
2890: 2a 2f 0a 20 20 50 67 6e 6f 20 2a 61 47 6f 62 62  */.  Pgno *aGobb
28a0: 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  le;             
28b0: 20 20 20 20 20 2f 2a 20 47 6f 62 62 6c 65 20 70       /* Gobble p
28c0: 6f 69 6e 74 20 66 6f 72 20 65 61 63 68 20 69 6e  oint for each in
28d0: 70 75 74 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 0a  put segment */..
28e0: 20 20 50 67 6e 6f 20 69 49 6e 64 69 72 65 63 74    Pgno iIndirect
28f0: 3b 0a 20 20 73 74 72 75 63 74 20 53 61 76 65 64  ;.  struct Saved
2900: 50 67 6e 6f 20 7b 0a 20 20 20 20 50 67 6e 6f 20  Pgno {.    Pgno 
2910: 69 50 67 6e 6f 3b 0a 20 20 20 20 69 6e 74 20 62  iPgno;.    int b
2920: 53 74 6f 72 65 3b 0a 20 20 7d 20 61 53 61 76 65  Store;.  } aSave
2930: 5b 32 5d 3b 0a 7d 3b 0a 0a 23 69 66 64 65 66 20  [2];.};..#ifdef 
2940: 4c 53 4d 5f 44 45 42 55 47 5f 45 58 50 45 4e 53  LSM_DEBUG_EXPENS
2950: 49 56 45 0a 73 74 61 74 69 63 20 69 6e 74 20 61  IVE.static int a
2960: 73 73 65 72 74 50 6f 69 6e 74 65 72 73 4f 6b 28  ssertPointersOk(
2970: 6c 73 6d 5f 64 62 20 2a 2c 20 53 65 67 6d 65 6e  lsm_db *, Segmen
2980: 74 20 2a 2c 20 53 65 67 6d 65 6e 74 20 2a 2c 20  t *, Segment *, 
2990: 69 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  int);.static int
29a0: 20 61 73 73 65 72 74 42 74 72 65 65 4f 6b 28 6c   assertBtreeOk(l
29b0: 73 6d 5f 64 62 20 2a 2c 20 53 65 67 6d 65 6e 74  sm_db *, Segment
29c0: 20 2a 29 3b 0a 73 74 61 74 69 63 20 76 6f 69 64   *);.static void
29d0: 20 61 73 73 65 72 74 52 75 6e 49 6e 4f 72 64 65   assertRunInOrde
29e0: 72 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 53  r(lsm_db *pDb, S
29f0: 65 67 6d 65 6e 74 20 2a 70 53 65 67 29 3b 0a 23  egment *pSeg);.#
2a00: 65 6c 73 65 0a 23 64 65 66 69 6e 65 20 61 73 73  else.#define ass
2a10: 65 72 74 52 75 6e 49 6e 4f 72 64 65 72 28 78 2c  ertRunInOrder(x,
2a20: 79 29 0a 23 64 65 66 69 6e 65 20 61 73 73 65 72  y).#define asser
2a30: 74 42 74 72 65 65 4f 6b 28 78 2c 79 29 0a 23 65  tBtreeOk(x,y).#e
2a40: 6e 64 69 66 0a 0a 0a 73 74 72 75 63 74 20 46 69  ndif...struct Fi
2a50: 6c 65 50 61 67 65 20 7b 20 75 38 20 2a 61 44 61  lePage { u8 *aDa
2a60: 74 61 3b 20 69 6e 74 20 6e 44 61 74 61 3b 20 7d  ta; int nData; }
2a70: 3b 0a 73 74 61 74 69 63 20 75 38 20 2a 66 73 50  ;.static u8 *fsP
2a80: 61 67 65 44 61 74 61 28 50 61 67 65 20 2a 70 50  ageData(Page *pP
2a90: 67 2c 20 69 6e 74 20 2a 70 6e 44 61 74 61 29 7b  g, int *pnData){
2aa0: 0a 20 20 2a 70 6e 44 61 74 61 20 3d 20 28 28 73  .  *pnData = ((s
2ab0: 74 72 75 63 74 20 46 69 6c 65 50 61 67 65 20 2a  truct FilePage *
2ac0: 29 28 70 50 67 29 29 2d 3e 6e 44 61 74 61 3b 0a  )(pPg))->nData;.
2ad0: 20 20 72 65 74 75 72 6e 20 28 28 73 74 72 75 63    return ((struc
2ae0: 74 20 46 69 6c 65 50 61 67 65 20 2a 29 28 70 50  t FilePage *)(pP
2af0: 67 29 29 2d 3e 61 44 61 74 61 3b 0a 7d 0a 2f 2a  g))->aData;.}./*
2b00: 55 4e 55 53 45 44 20 73 74 61 74 69 63 20 75 38  UNUSED static u8
2b10: 20 2a 66 73 50 61 67 65 44 61 74 61 50 74 72 28   *fsPageDataPtr(
2b20: 50 61 67 65 20 2a 70 50 67 29 7b 0a 20 20 72 65  Page *pPg){.  re
2b30: 74 75 72 6e 20 28 28 73 74 72 75 63 74 20 46 69  turn ((struct Fi
2b40: 6c 65 50 61 67 65 20 2a 29 28 70 50 67 29 29 2d  lePage *)(pPg))-
2b50: 3e 61 44 61 74 61 3b 0a 7d 2a 2f 0a 0a 2f 2a 0a  >aData;.}*/../*.
2b60: 2a 2a 20 57 72 69 74 65 20 6e 56 61 6c 20 61 73  ** Write nVal as
2b70: 20 61 20 31 36 2d 62 69 74 20 75 6e 73 69 67 6e   a 16-bit unsign
2b80: 65 64 20 62 69 67 2d 65 6e 64 69 61 6e 20 69 6e  ed big-endian in
2b90: 74 65 67 65 72 20 69 6e 74 6f 20 62 75 66 66 65  teger into buffe
2ba0: 72 20 61 4f 75 74 2e 0a 2a 2f 0a 76 6f 69 64 20  r aOut..*/.void 
2bb0: 6c 73 6d 50 75 74 55 31 36 28 75 38 20 2a 61 4f  lsmPutU16(u8 *aO
2bc0: 75 74 2c 20 75 31 36 20 6e 56 61 6c 29 7b 0a 20  ut, u16 nVal){. 
2bd0: 20 61 4f 75 74 5b 30 5d 20 3d 20 28 75 38 29 28   aOut[0] = (u8)(
2be0: 28 6e 56 61 6c 3e 3e 38 29 20 26 20 30 78 46 46  (nVal>>8) & 0xFF
2bf0: 29 3b 0a 20 20 61 4f 75 74 5b 31 5d 20 3d 20 28  );.  aOut[1] = (
2c00: 75 38 29 28 6e 56 61 6c 20 26 20 30 78 46 46 29  u8)(nVal & 0xFF)
2c10: 3b 0a 7d 0a 0a 76 6f 69 64 20 6c 73 6d 50 75 74  ;.}..void lsmPut
2c20: 55 33 32 28 75 38 20 2a 61 4f 75 74 2c 20 75 33  U32(u8 *aOut, u3
2c30: 32 20 6e 56 61 6c 29 7b 0a 20 20 61 4f 75 74 5b  2 nVal){.  aOut[
2c40: 30 5d 20 3d 20 28 75 38 29 28 28 6e 56 61 6c 3e  0] = (u8)((nVal>
2c50: 3e 32 34 29 20 26 20 30 78 46 46 29 3b 0a 20 20  >24) & 0xFF);.  
2c60: 61 4f 75 74 5b 31 5d 20 3d 20 28 75 38 29 28 28  aOut[1] = (u8)((
2c70: 6e 56 61 6c 3e 3e 31 36 29 20 26 20 30 78 46 46  nVal>>16) & 0xFF
2c80: 29 3b 0a 20 20 61 4f 75 74 5b 32 5d 20 3d 20 28  );.  aOut[2] = (
2c90: 75 38 29 28 28 6e 56 61 6c 3e 3e 20 38 29 20 26  u8)((nVal>> 8) &
2ca0: 20 30 78 46 46 29 3b 0a 20 20 61 4f 75 74 5b 33   0xFF);.  aOut[3
2cb0: 5d 20 3d 20 28 75 38 29 28 28 6e 56 61 6c 20 20  ] = (u8)((nVal  
2cc0: 20 20 29 20 26 20 30 78 46 46 29 3b 0a 7d 0a 0a    ) & 0xFF);.}..
2cd0: 69 6e 74 20 6c 73 6d 47 65 74 55 31 36 28 75 38  int lsmGetU16(u8
2ce0: 20 2a 61 4f 75 74 29 7b 0a 20 20 72 65 74 75 72   *aOut){.  retur
2cf0: 6e 20 28 61 4f 75 74 5b 30 5d 20 3c 3c 20 38 29  n (aOut[0] << 8)
2d00: 20 2b 20 61 4f 75 74 5b 31 5d 3b 0a 7d 0a 0a 75   + aOut[1];.}..u
2d10: 33 32 20 6c 73 6d 47 65 74 55 33 32 28 75 38 20  32 lsmGetU32(u8 
2d20: 2a 61 4f 75 74 29 7b 0a 20 20 72 65 74 75 72 6e  *aOut){.  return
2d30: 20 28 28 75 33 32 29 61 4f 75 74 5b 30 5d 20 3c   ((u32)aOut[0] <
2d40: 3c 20 32 34 29 20 0a 20 20 20 20 20 20 20 2b 20  < 24) .       + 
2d50: 28 28 75 33 32 29 61 4f 75 74 5b 31 5d 20 3c 3c  ((u32)aOut[1] <<
2d60: 20 31 36 29 20 0a 20 20 20 20 20 20 20 2b 20 28   16) .       + (
2d70: 28 75 33 32 29 61 4f 75 74 5b 32 5d 20 3c 3c 20  (u32)aOut[2] << 
2d80: 38 29 20 0a 20 20 20 20 20 20 20 2b 20 28 28 75  8) .       + ((u
2d90: 33 32 29 61 4f 75 74 5b 33 5d 29 3b 0a 7d 0a 0a  32)aOut[3]);.}..
2da0: 75 36 34 20 6c 73 6d 47 65 74 55 36 34 28 75 38  u64 lsmGetU64(u8
2db0: 20 2a 61 4f 75 74 29 7b 0a 20 20 72 65 74 75 72   *aOut){.  retur
2dc0: 6e 20 28 28 75 36 34 29 61 4f 75 74 5b 30 5d 20  n ((u64)aOut[0] 
2dd0: 3c 3c 20 35 36 29 20 0a 20 20 20 20 20 20 20 2b  << 56) .       +
2de0: 20 28 28 75 36 34 29 61 4f 75 74 5b 31 5d 20 3c   ((u64)aOut[1] <
2df0: 3c 20 34 38 29 20 0a 20 20 20 20 20 20 20 2b 20  < 48) .       + 
2e00: 28 28 75 36 34 29 61 4f 75 74 5b 32 5d 20 3c 3c  ((u64)aOut[2] <<
2e10: 20 34 30 29 20 0a 20 20 20 20 20 20 20 2b 20 28   40) .       + (
2e20: 28 75 36 34 29 61 4f 75 74 5b 33 5d 20 3c 3c 20  (u64)aOut[3] << 
2e30: 33 32 29 20 0a 20 20 20 20 20 20 20 2b 20 28 28  32) .       + ((
2e40: 75 36 34 29 61 4f 75 74 5b 34 5d 20 3c 3c 20 32  u64)aOut[4] << 2
2e50: 34 29 0a 20 20 20 20 20 20 20 2b 20 28 28 75 33  4).       + ((u3
2e60: 32 29 61 4f 75 74 5b 35 5d 20 3c 3c 20 31 36 29  2)aOut[5] << 16)
2e70: 20 0a 20 20 20 20 20 20 20 2b 20 28 28 75 33 32   .       + ((u32
2e80: 29 61 4f 75 74 5b 36 5d 20 3c 3c 20 38 29 20 0a  )aOut[6] << 8) .
2e90: 20 20 20 20 20 20 20 2b 20 28 28 75 33 32 29 61         + ((u32)a
2ea0: 4f 75 74 5b 37 5d 29 3b 0a 7d 0a 0a 76 6f 69 64  Out[7]);.}..void
2eb0: 20 6c 73 6d 50 75 74 55 36 34 28 75 38 20 2a 61   lsmPutU64(u8 *a
2ec0: 4f 75 74 2c 20 75 36 34 20 6e 56 61 6c 29 7b 0a  Out, u64 nVal){.
2ed0: 20 20 61 4f 75 74 5b 30 5d 20 3d 20 28 75 38 29    aOut[0] = (u8)
2ee0: 28 28 6e 56 61 6c 3e 3e 35 36 29 20 26 20 30 78  ((nVal>>56) & 0x
2ef0: 46 46 29 3b 0a 20 20 61 4f 75 74 5b 31 5d 20 3d  FF);.  aOut[1] =
2f00: 20 28 75 38 29 28 28 6e 56 61 6c 3e 3e 34 38 29   (u8)((nVal>>48)
2f10: 20 26 20 30 78 46 46 29 3b 0a 20 20 61 4f 75 74   & 0xFF);.  aOut
2f20: 5b 32 5d 20 3d 20 28 75 38 29 28 28 6e 56 61 6c  [2] = (u8)((nVal
2f30: 3e 3e 34 30 29 20 26 20 30 78 46 46 29 3b 0a 20  >>40) & 0xFF);. 
2f40: 20 61 4f 75 74 5b 33 5d 20 3d 20 28 75 38 29 28   aOut[3] = (u8)(
2f50: 28 6e 56 61 6c 3e 3e 33 32 29 20 26 20 30 78 46  (nVal>>32) & 0xF
2f60: 46 29 3b 0a 20 20 61 4f 75 74 5b 34 5d 20 3d 20  F);.  aOut[4] = 
2f70: 28 75 38 29 28 28 6e 56 61 6c 3e 3e 32 34 29 20  (u8)((nVal>>24) 
2f80: 26 20 30 78 46 46 29 3b 0a 20 20 61 4f 75 74 5b  & 0xFF);.  aOut[
2f90: 35 5d 20 3d 20 28 75 38 29 28 28 6e 56 61 6c 3e  5] = (u8)((nVal>
2fa0: 3e 31 36 29 20 26 20 30 78 46 46 29 3b 0a 20 20  >16) & 0xFF);.  
2fb0: 61 4f 75 74 5b 36 5d 20 3d 20 28 75 38 29 28 28  aOut[6] = (u8)((
2fc0: 6e 56 61 6c 3e 3e 20 38 29 20 26 20 30 78 46 46  nVal>> 8) & 0xFF
2fd0: 29 3b 0a 20 20 61 4f 75 74 5b 37 5d 20 3d 20 28  );.  aOut[7] = (
2fe0: 75 38 29 28 28 6e 56 61 6c 20 20 20 20 29 20 26  u8)((nVal    ) &
2ff0: 20 30 78 46 46 29 3b 0a 7d 0a 0a 73 74 61 74 69   0xFF);.}..stati
3000: 63 20 69 6e 74 20 73 6f 72 74 65 64 42 6c 6f 62  c int sortedBlob
3010: 47 72 6f 77 28 6c 73 6d 5f 65 6e 76 20 2a 70 45  Grow(lsm_env *pE
3020: 6e 76 2c 20 42 6c 6f 62 20 2a 70 42 6c 6f 62 2c  nv, Blob *pBlob,
3030: 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 61   int nData){.  a
3040: 73 73 65 72 74 28 20 70 42 6c 6f 62 2d 3e 70 45  ssert( pBlob->pE
3050: 6e 76 3d 3d 70 45 6e 76 20 7c 7c 20 28 70 42 6c  nv==pEnv || (pBl
3060: 6f 62 2d 3e 70 45 6e 76 3d 3d 30 20 26 26 20 70  ob->pEnv==0 && p
3070: 42 6c 6f 62 2d 3e 70 44 61 74 61 3d 3d 30 29 20  Blob->pData==0) 
3080: 29 3b 0a 20 20 69 66 28 20 70 42 6c 6f 62 2d 3e  );.  if( pBlob->
3090: 6e 41 6c 6c 6f 63 3c 6e 44 61 74 61 20 29 7b 0a  nAlloc<nData ){.
30a0: 20 20 20 20 70 42 6c 6f 62 2d 3e 70 44 61 74 61      pBlob->pData
30b0: 20 3d 20 6c 73 6d 52 65 61 6c 6c 6f 63 4f 72 46   = lsmReallocOrF
30c0: 72 65 65 28 70 45 6e 76 2c 20 70 42 6c 6f 62 2d  ree(pEnv, pBlob-
30d0: 3e 70 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a  >pData, nData);.
30e0: 20 20 20 20 69 66 28 20 21 70 42 6c 6f 62 2d 3e      if( !pBlob->
30f0: 70 44 61 74 61 20 29 20 72 65 74 75 72 6e 20 4c  pData ) return L
3100: 53 4d 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20  SM_NOMEM_BKPT;. 
3110: 20 20 20 70 42 6c 6f 62 2d 3e 6e 41 6c 6c 6f 63     pBlob->nAlloc
3120: 20 3d 20 6e 44 61 74 61 3b 0a 20 20 20 20 70 42   = nData;.    pB
3130: 6c 6f 62 2d 3e 70 45 6e 76 20 3d 20 70 45 6e 76  lob->pEnv = pEnv
3140: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 4c  ;.  }.  return L
3150: 53 4d 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63  SM_OK;.}..static
3160: 20 69 6e 74 20 73 6f 72 74 65 64 42 6c 6f 62 53   int sortedBlobS
3170: 65 74 28 6c 73 6d 5f 65 6e 76 20 2a 70 45 6e 76  et(lsm_env *pEnv
3180: 2c 20 42 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20 76  , Blob *pBlob, v
3190: 6f 69 64 20 2a 70 44 61 74 61 2c 20 69 6e 74 20  oid *pData, int 
31a0: 6e 44 61 74 61 29 7b 0a 20 20 69 66 28 20 73 6f  nData){.  if( so
31b0: 72 74 65 64 42 6c 6f 62 47 72 6f 77 28 70 45 6e  rtedBlobGrow(pEn
31c0: 76 2c 20 70 42 6c 6f 62 2c 20 6e 44 61 74 61 29  v, pBlob, nData)
31d0: 20 29 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4e 4f   ) return LSM_NO
31e0: 4d 45 4d 3b 0a 20 20 6d 65 6d 63 70 79 28 70 42  MEM;.  memcpy(pB
31f0: 6c 6f 62 2d 3e 70 44 61 74 61 2c 20 70 44 61 74  lob->pData, pDat
3200: 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 70 42 6c  a, nData);.  pBl
3210: 6f 62 2d 3e 6e 44 61 74 61 20 3d 20 6e 44 61 74  ob->nData = nDat
3220: 61 3b 0a 20 20 72 65 74 75 72 6e 20 4c 53 4d 5f  a;.  return LSM_
3230: 4f 4b 3b 0a 7d 0a 0a 23 69 66 20 30 0a 73 74 61  OK;.}..#if 0.sta
3240: 74 69 63 20 69 6e 74 20 73 6f 72 74 65 64 42 6c  tic int sortedBl
3250: 6f 62 43 6f 70 79 28 42 6c 6f 62 20 2a 70 44 65  obCopy(Blob *pDe
3260: 73 74 2c 20 42 6c 6f 62 20 2a 70 53 72 63 29 7b  st, Blob *pSrc){
3270: 0a 20 20 72 65 74 75 72 6e 20 73 6f 72 74 65 64  .  return sorted
3280: 42 6c 6f 62 53 65 74 28 70 44 65 73 74 2c 20 70  BlobSet(pDest, p
3290: 53 72 63 2d 3e 70 44 61 74 61 2c 20 70 53 72 63  Src->pData, pSrc
32a0: 2d 3e 6e 44 61 74 61 29 3b 0a 7d 0a 23 65 6e 64  ->nData);.}.#end
32b0: 69 66 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  if..static void 
32c0: 73 6f 72 74 65 64 42 6c 6f 62 46 72 65 65 28 42  sortedBlobFree(B
32d0: 6c 6f 62 20 2a 70 42 6c 6f 62 29 7b 0a 20 20 61  lob *pBlob){.  a
32e0: 73 73 65 72 74 28 20 70 42 6c 6f 62 2d 3e 70 45  ssert( pBlob->pE
32f0: 6e 76 20 7c 7c 20 70 42 6c 6f 62 2d 3e 70 44 61  nv || pBlob->pDa
3300: 74 61 3d 3d 30 20 29 3b 0a 20 20 69 66 28 20 70  ta==0 );.  if( p
3310: 42 6c 6f 62 2d 3e 70 44 61 74 61 20 29 20 6c 73  Blob->pData ) ls
3320: 6d 46 72 65 65 28 70 42 6c 6f 62 2d 3e 70 45 6e  mFree(pBlob->pEn
3330: 76 2c 20 70 42 6c 6f 62 2d 3e 70 44 61 74 61 29  v, pBlob->pData)
3340: 3b 0a 20 20 6d 65 6d 73 65 74 28 70 42 6c 6f 62  ;.  memset(pBlob
3350: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 42 6c 6f 62  , 0, sizeof(Blob
3360: 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  ));.}..static in
3370: 74 20 73 6f 72 74 65 64 52 65 61 64 44 61 74 61  t sortedReadData
3380: 28 0a 20 20 53 65 67 6d 65 6e 74 20 2a 70 53 65  (.  Segment *pSe
3390: 67 2c 0a 20 20 50 61 67 65 20 2a 70 50 67 2c 0a  g,.  Page *pPg,.
33a0: 20 20 69 6e 74 20 69 4f 66 66 2c 0a 20 20 69 6e    int iOff,.  in
33b0: 74 20 6e 42 79 74 65 2c 0a 20 20 76 6f 69 64 20  t nByte,.  void 
33c0: 2a 2a 70 70 44 61 74 61 2c 0a 20 20 42 6c 6f 62  **ppData,.  Blob
33d0: 20 2a 70 42 6c 6f 62 0a 29 7b 0a 20 20 69 6e 74   *pBlob.){.  int
33e0: 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20   rc = LSM_OK;.  
33f0: 69 6e 74 20 69 45 6e 64 3b 0a 20 20 69 6e 74 20  int iEnd;.  int 
3400: 6e 44 61 74 61 3b 0a 20 20 69 6e 74 20 6e 43 65  nData;.  int nCe
3410: 6c 6c 3b 0a 20 20 75 38 20 2a 61 44 61 74 61 3b  ll;.  u8 *aData;
3420: 0a 0a 20 20 61 44 61 74 61 20 3d 20 66 73 50 61  ..  aData = fsPa
3430: 67 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44 61  geData(pPg, &nDa
3440: 74 61 29 3b 0a 20 20 6e 43 65 6c 6c 20 3d 20 6c  ta);.  nCell = l
3450: 73 6d 47 65 74 55 31 36 28 26 61 44 61 74 61 5b  smGetU16(&aData[
3460: 53 45 47 4d 45 4e 54 5f 4e 52 45 43 4f 52 44 5f  SEGMENT_NRECORD_
3470: 4f 46 46 53 45 54 28 6e 44 61 74 61 29 5d 29 3b  OFFSET(nData)]);
3480: 0a 20 20 69 45 6e 64 20 3d 20 53 45 47 4d 45 4e  .  iEnd = SEGMEN
3490: 54 5f 45 4f 46 28 6e 44 61 74 61 2c 20 6e 43 65  T_EOF(nData, nCe
34a0: 6c 6c 29 3b 0a 20 20 61 73 73 65 72 74 28 20 69  ll);.  assert( i
34b0: 45 6e 64 3e 30 20 26 26 20 69 45 6e 64 3c 6e 44  End>0 && iEnd<nD
34c0: 61 74 61 20 29 3b 0a 0a 20 20 69 66 28 20 69 4f  ata );..  if( iO
34d0: 66 66 2b 6e 42 79 74 65 3c 3d 69 45 6e 64 20 29  ff+nByte<=iEnd )
34e0: 7b 0a 20 20 20 20 2a 70 70 44 61 74 61 20 3d 20  {.    *ppData = 
34f0: 28 76 6f 69 64 20 2a 29 26 61 44 61 74 61 5b 69  (void *)&aData[i
3500: 4f 66 66 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Off];.  }else{. 
3510: 20 20 20 69 6e 74 20 6e 52 65 6d 20 3d 20 6e 42     int nRem = nB
3520: 79 74 65 3b 0a 20 20 20 20 69 6e 74 20 69 20 3d  yte;.    int i =
3530: 20 69 4f 66 66 3b 0a 20 20 20 20 75 38 20 2a 61   iOff;.    u8 *a
3540: 44 65 73 74 3b 0a 0a 20 20 20 20 2f 2a 20 4d 61  Dest;..    /* Ma
3550: 6b 65 20 73 75 72 65 20 74 68 65 20 62 6c 6f 62  ke sure the blob
3560: 20 69 73 20 62 69 67 20 65 6e 6f 75 67 68 20 74   is big enough t
3570: 6f 20 73 74 6f 72 65 20 74 68 65 20 76 61 6c 75  o store the valu
3580: 65 20 62 65 69 6e 67 20 6c 6f 61 64 65 64 2e 20  e being loaded. 
3590: 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73 6f 72 74  */.    rc = sort
35a0: 65 64 42 6c 6f 62 47 72 6f 77 28 6c 73 6d 50 61  edBlobGrow(lsmPa
35b0: 67 65 45 6e 76 28 70 50 67 29 2c 20 70 42 6c 6f  geEnv(pPg), pBlo
35c0: 62 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 69  b, nByte);.    i
35d0: 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20  f( rc!=LSM_OK ) 
35e0: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 70  return rc;.    p
35f0: 42 6c 6f 62 2d 3e 6e 44 61 74 61 20 3d 20 6e 42  Blob->nData = nB
3600: 79 74 65 3b 0a 20 20 20 20 61 44 65 73 74 20 3d  yte;.    aDest =
3610: 20 28 75 38 20 2a 29 70 42 6c 6f 62 2d 3e 70 44   (u8 *)pBlob->pD
3620: 61 74 61 3b 0a 20 20 20 20 2a 70 70 44 61 74 61  ata;.    *ppData
3630: 20 3d 20 70 42 6c 6f 62 2d 3e 70 44 61 74 61 3b   = pBlob->pData;
3640: 0a 0a 20 20 20 20 2f 2a 20 49 6e 63 72 65 6d 65  ..    /* Increme
3650: 6e 74 20 74 68 65 20 70 6f 69 6e 74 65 72 20 70  nt the pointer p
3660: 61 67 65 73 20 72 65 66 2d 63 6f 75 6e 74 2e 20  ages ref-count. 
3670: 2a 2f 0a 20 20 20 20 6c 73 6d 46 73 50 61 67 65  */.    lsmFsPage
3680: 52 65 66 28 70 50 67 29 3b 0a 0a 20 20 20 20 77  Ref(pPg);..    w
3690: 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b  hile( rc==LSM_OK
36a0: 20 29 7b 0a 20 20 20 20 20 20 50 61 67 65 20 2a   ){.      Page *
36b0: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 69 6e 74  pNext;.      int
36c0: 20 66 6c 61 67 73 3b 0a 0a 20 20 20 20 20 20 2f   flags;..      /
36d0: 2a 20 43 6f 70 79 20 64 61 74 61 20 66 72 6f 6d  * Copy data from
36e0: 20 70 50 67 20 69 6e 74 6f 20 74 68 65 20 6f 75   pPg into the ou
36f0: 74 70 75 74 20 62 75 66 66 65 72 2e 20 2a 2f 0a  tput buffer. */.
3700: 20 20 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 20        int nCopy 
3710: 3d 20 4c 53 4d 5f 4d 49 4e 28 6e 52 65 6d 2c 20  = LSM_MIN(nRem, 
3720: 69 45 6e 64 2d 69 29 3b 0a 20 20 20 20 20 20 69  iEnd-i);.      i
3730: 66 28 20 6e 43 6f 70 79 3e 30 20 29 7b 0a 20 20  f( nCopy>0 ){.  
3740: 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 61 44        memcpy(&aD
3750: 65 73 74 5b 6e 42 79 74 65 2d 6e 52 65 6d 5d 2c  est[nByte-nRem],
3760: 20 26 61 44 61 74 61 5b 69 5d 2c 20 6e 43 6f 70   &aData[i], nCop
3770: 79 29 3b 0a 20 20 20 20 20 20 20 20 6e 52 65 6d  y);.        nRem
3780: 20 2d 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 20   -= nCopy;.     
3790: 20 20 20 69 20 2b 3d 20 6e 43 6f 70 79 3b 0a 20     i += nCopy;. 
37a0: 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6e         assert( n
37b0: 52 65 6d 3d 3d 30 20 7c 7c 20 69 3d 3d 69 45 6e  Rem==0 || i==iEn
37c0: 64 20 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  d );.      }.   
37d0: 20 20 20 61 73 73 65 72 74 28 20 6e 52 65 6d 3e     assert( nRem>
37e0: 3d 30 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20  =0 );.      if( 
37f0: 6e 52 65 6d 3d 3d 30 20 29 20 62 72 65 61 6b 3b  nRem==0 ) break;
3800: 0a 20 20 20 20 20 20 69 20 2d 3d 20 69 45 6e 64  .      i -= iEnd
3810: 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 47 72 61 62  ;..      /* Grab
3820: 20 74 68 65 20 6e 65 78 74 20 70 61 67 65 20 69   the next page i
3830: 6e 20 74 68 65 20 73 65 67 6d 65 6e 74 20 2a 2f  n the segment */
3840: 0a 0a 20 20 20 20 20 20 64 6f 20 7b 0a 20 20 20  ..      do {.   
3850: 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 44       rc = lsmFsD
3860: 62 50 61 67 65 4e 65 78 74 28 70 53 65 67 2c 20  bPageNext(pSeg, 
3870: 70 50 67 2c 20 31 2c 20 26 70 4e 65 78 74 29 3b  pPg, 1, &pNext);
3880: 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d  .        if( rc=
3890: 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 4e 65 78 74  =LSM_OK && pNext
38a0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
38b0: 20 72 63 20 3d 20 4c 53 4d 5f 43 4f 52 52 55 50   rc = LSM_CORRUP
38c0: 54 5f 42 4b 50 54 3b 0a 20 20 20 20 20 20 20 20  T_BKPT;.        
38d0: 7d 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  }.        if( rc
38e0: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20   ) break;.      
38f0: 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61    lsmFsPageRelea
3900: 73 65 28 70 50 67 29 3b 0a 20 20 20 20 20 20 20  se(pPg);.       
3910: 20 70 50 67 20 3d 20 70 4e 65 78 74 3b 0a 20 20   pPg = pNext;.  
3920: 20 20 20 20 20 20 61 44 61 74 61 20 3d 20 66 73        aData = fs
3930: 50 61 67 65 44 61 74 61 28 70 50 67 2c 20 26 6e  PageData(pPg, &n
3940: 44 61 74 61 29 3b 0a 20 20 20 20 20 20 20 20 66  Data);.        f
3950: 6c 61 67 73 20 3d 20 6c 73 6d 47 65 74 55 31 36  lags = lsmGetU16
3960: 28 26 61 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f  (&aData[SEGMENT_
3970: 46 4c 41 47 53 5f 4f 46 46 53 45 54 28 6e 44 61  FLAGS_OFFSET(nDa
3980: 74 61 29 5d 29 3b 0a 20 20 20 20 20 20 7d 77 68  ta)]);.      }wh
3990: 69 6c 65 28 20 66 6c 61 67 73 26 53 45 47 4d 45  ile( flags&SEGME
39a0: 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 20 29 3b  NT_BTREE_FLAG );
39b0: 0a 0a 20 20 20 20 20 20 69 45 6e 64 20 3d 20 53  ..      iEnd = S
39c0: 45 47 4d 45 4e 54 5f 45 4f 46 28 6e 44 61 74 61  EGMENT_EOF(nData
39d0: 2c 20 6c 73 6d 47 65 74 55 31 36 28 26 61 44 61  , lsmGetU16(&aDa
39e0: 74 61 5b 6e 44 61 74 61 2d 32 5d 29 29 3b 0a 20  ta[nData-2]));. 
39f0: 20 20 20 20 20 61 73 73 65 72 74 28 20 69 45 6e       assert( iEn
3a00: 64 3e 30 20 26 26 20 69 45 6e 64 3c 6e 44 61 74  d>0 && iEnd<nDat
3a10: 61 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  a );.    }..    
3a20: 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61 73 65  lsmFsPageRelease
3a30: 28 70 50 67 29 3b 0a 20 20 7d 0a 0a 20 20 72 65  (pPg);.  }..  re
3a40: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
3a50: 69 63 20 69 6e 74 20 70 61 67 65 47 65 74 4e 52  ic int pageGetNR
3a60: 65 63 28 75 38 20 2a 61 44 61 74 61 2c 20 69 6e  ec(u8 *aData, in
3a70: 74 20 6e 44 61 74 61 29 7b 0a 20 20 72 65 74 75  t nData){.  retu
3a80: 72 6e 20 28 69 6e 74 29 6c 73 6d 47 65 74 55 31  rn (int)lsmGetU1
3a90: 36 28 26 61 44 61 74 61 5b 53 45 47 4d 45 4e 54  6(&aData[SEGMENT
3aa0: 5f 4e 52 45 43 4f 52 44 5f 4f 46 46 53 45 54 28  _NRECORD_OFFSET(
3ab0: 6e 44 61 74 61 29 5d 29 3b 0a 7d 0a 0a 73 74 61  nData)]);.}..sta
3ac0: 74 69 63 20 50 67 6e 6f 20 70 61 67 65 47 65 74  tic Pgno pageGet
3ad0: 50 74 72 28 75 38 20 2a 61 44 61 74 61 2c 20 69  Ptr(u8 *aData, i
3ae0: 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 72 65 74  nt nData){.  ret
3af0: 75 72 6e 20 28 50 67 6e 6f 29 6c 73 6d 47 65 74  urn (Pgno)lsmGet
3b00: 55 36 34 28 26 61 44 61 74 61 5b 53 45 47 4d 45  U64(&aData[SEGME
3b10: 4e 54 5f 50 4f 49 4e 54 45 52 5f 4f 46 46 53 45  NT_POINTER_OFFSE
3b20: 54 28 6e 44 61 74 61 29 5d 29 3b 0a 7d 0a 0a 73  T(nData)]);.}..s
3b30: 74 61 74 69 63 20 69 6e 74 20 70 61 67 65 47 65  tatic int pageGe
3b40: 74 46 6c 61 67 73 28 75 38 20 2a 61 44 61 74 61  tFlags(u8 *aData
3b50: 2c 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20  , int nData){.  
3b60: 72 65 74 75 72 6e 20 28 69 6e 74 29 6c 73 6d 47  return (int)lsmG
3b70: 65 74 55 31 36 28 26 61 44 61 74 61 5b 53 45 47  etU16(&aData[SEG
3b80: 4d 45 4e 54 5f 46 4c 41 47 53 5f 4f 46 46 53 45  MENT_FLAGS_OFFSE
3b90: 54 28 6e 44 61 74 61 29 5d 29 3b 0a 7d 0a 0a 73  T(nData)]);.}..s
3ba0: 74 61 74 69 63 20 75 38 20 2a 70 61 67 65 47 65  tatic u8 *pageGe
3bb0: 74 43 65 6c 6c 28 75 38 20 2a 61 44 61 74 61 2c  tCell(u8 *aData,
3bc0: 20 69 6e 74 20 6e 44 61 74 61 2c 20 69 6e 74 20   int nData, int 
3bd0: 69 43 65 6c 6c 29 7b 0a 20 20 72 65 74 75 72 6e  iCell){.  return
3be0: 20 26 61 44 61 74 61 5b 6c 73 6d 47 65 74 55 31   &aData[lsmGetU1
3bf0: 36 28 26 61 44 61 74 61 5b 53 45 47 4d 45 4e 54  6(&aData[SEGMENT
3c00: 5f 43 45 4c 4c 50 54 52 5f 4f 46 46 53 45 54 28  _CELLPTR_OFFSET(
3c10: 6e 44 61 74 61 2c 20 69 43 65 6c 6c 29 5d 29 5d  nData, iCell)])]
3c20: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
3c30: 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  n the number of 
3c40: 63 65 6c 6c 73 20 6f 6e 20 70 61 67 65 20 70 50  cells on page pP
3c50: 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  g..*/.static int
3c60: 20 70 61 67 65 4f 62 6a 47 65 74 4e 52 65 63 28   pageObjGetNRec(
3c70: 50 61 67 65 20 2a 70 50 67 29 7b 0a 20 20 69 6e  Page *pPg){.  in
3c80: 74 20 6e 44 61 74 61 3b 0a 20 20 75 38 20 2a 61  t nData;.  u8 *a
3c90: 44 61 74 61 20 3d 20 6c 73 6d 46 73 50 61 67 65  Data = lsmFsPage
3ca0: 44 61 74 61 28 70 50 67 2c 20 26 6e 44 61 74 61  Data(pPg, &nData
3cb0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 61 67 65  );.  return page
3cc0: 47 65 74 4e 52 65 63 28 61 44 61 74 61 2c 20 6e  GetNRec(aData, n
3cd0: 44 61 74 61 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Data);.}../*.** 
3ce0: 52 65 74 75 72 6e 20 74 68 65 20 64 65 63 6f 64  Return the decod
3cf0: 65 64 20 28 70 6f 73 73 69 62 6c 79 20 72 65 6c  ed (possibly rel
3d00: 61 74 69 76 65 29 20 70 6f 69 6e 74 65 72 20 76  ative) pointer v
3d10: 61 6c 75 65 20 73 74 6f 72 65 64 20 69 6e 20 63  alue stored in c
3d20: 65 6c 6c 20 0a 2a 2a 20 69 43 65 6c 6c 20 66 72  ell .** iCell fr
3d30: 6f 6d 20 70 61 67 65 20 61 44 61 74 61 2f 6e 44  om page aData/nD
3d40: 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50  ata..*/.static P
3d50: 67 6e 6f 20 70 61 67 65 47 65 74 52 65 63 6f 72  gno pageGetRecor
3d60: 64 50 74 72 28 75 38 20 2a 61 44 61 74 61 2c 20  dPtr(u8 *aData, 
3d70: 69 6e 74 20 6e 44 61 74 61 2c 20 69 6e 74 20 69  int nData, int i
3d80: 43 65 6c 6c 29 7b 0a 20 20 50 67 6e 6f 20 69 52  Cell){.  Pgno iR
3d90: 65 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  et;             
3da0: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
3db0: 72 6e 20 76 61 6c 75 65 20 2a 2f 0a 20 20 75 38  rn value */.  u8
3dc0: 20 2a 61 43 65 6c 6c 3b 20 20 20 20 20 20 20 20   *aCell;        
3dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3de0: 20 50 6f 69 6e 74 65 72 20 74 6f 20 63 65 6c 6c   Pointer to cell
3df0: 20 69 43 65 6c 6c 20 2a 2f 0a 0a 20 20 61 73 73   iCell */..  ass
3e00: 65 72 74 28 20 69 43 65 6c 6c 3c 70 61 67 65 47  ert( iCell<pageG
3e10: 65 74 4e 52 65 63 28 61 44 61 74 61 2c 20 6e 44  etNRec(aData, nD
3e20: 61 74 61 29 20 26 26 20 69 43 65 6c 6c 3e 3d 30  ata) && iCell>=0
3e30: 20 29 3b 0a 20 20 61 43 65 6c 6c 20 3d 20 70 61   );.  aCell = pa
3e40: 67 65 47 65 74 43 65 6c 6c 28 61 44 61 74 61 2c  geGetCell(aData,
3e50: 20 6e 44 61 74 61 2c 20 69 43 65 6c 6c 29 3b 0a   nData, iCell);.
3e60: 20 20 6c 73 6d 56 61 72 69 6e 74 47 65 74 36 34    lsmVarintGet64
3e70: 28 26 61 43 65 6c 6c 5b 31 5d 2c 20 26 69 52 65  (&aCell[1], &iRe
3e80: 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 69 52 65  t);.  return iRe
3e90: 74 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 75 38 20  t;.}..static u8 
3ea0: 2a 70 61 67 65 47 65 74 4b 65 79 28 0a 20 20 53  *pageGetKey(.  S
3eb0: 65 67 6d 65 6e 74 20 2a 70 53 65 67 2c 20 20 20  egment *pSeg,   
3ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3ed0: 2a 20 53 65 67 6d 65 6e 74 20 70 50 67 20 62 65  * Segment pPg be
3ee0: 6c 6f 6e 67 73 20 74 6f 20 2a 2f 0a 20 20 50 61  longs to */.  Pa
3ef0: 67 65 20 2a 70 50 67 2c 20 20 20 20 20 20 20 20  ge *pPg,        
3f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3f10: 20 50 61 67 65 20 74 6f 20 72 65 61 64 20 66 72   Page to read fr
3f20: 6f 6d 20 2a 2f 0a 20 20 69 6e 74 20 69 43 65 6c  om */.  int iCel
3f30: 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
3f40: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78          /* Index
3f50: 20 6f 66 20 63 65 6c 6c 20 6f 6e 20 70 61 67 65   of cell on page
3f60: 20 74 6f 20 72 65 61 64 20 2a 2f 0a 20 20 69 6e   to read */.  in
3f70: 74 20 2a 70 69 54 6f 70 69 63 2c 20 20 20 20 20  t *piTopic,     
3f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3f90: 20 4f 55 54 3a 20 54 6f 70 69 63 20 61 73 73 6f   OUT: Topic asso
3fa0: 63 69 61 74 65 64 20 77 69 74 68 20 74 68 69 73  ciated with this
3fb0: 20 6b 65 79 20 2a 2f 0a 20 20 69 6e 74 20 2a 70   key */.  int *p
3fc0: 6e 4b 65 79 2c 20 20 20 20 20 20 20 20 20 20 20  nKey,           
3fd0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
3fe0: 3a 20 53 69 7a 65 20 6f 66 20 6b 65 79 20 69 6e  : Size of key in
3ff0: 20 62 79 74 65 73 20 2a 2f 0a 20 20 42 6c 6f 62   bytes */.  Blob
4000: 20 2a 70 42 6c 6f 62 20 20 20 20 20 20 20 20 20   *pBlob         
4010: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
4020: 66 20 72 65 71 75 69 72 65 64 2c 20 75 73 65 20  f required, use 
4030: 74 68 69 73 20 66 6f 72 20 64 79 6e 61 6d 69 63  this for dynamic
4040: 20 6d 65 6d 6f 72 79 20 2a 2f 0a 29 7b 0a 20 20   memory */.){.  
4050: 75 38 20 2a 70 4b 65 79 3b 0a 20 20 69 6e 74 20  u8 *pKey;.  int 
4060: 6e 44 75 6d 6d 79 3b 0a 20 20 69 6e 74 20 65 54  nDummy;.  int eT
4070: 79 70 65 3b 0a 20 20 75 38 20 2a 61 44 61 74 61  ype;.  u8 *aData
4080: 3b 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a 0a  ;.  int nData;..
4090: 20 20 61 44 61 74 61 20 3d 20 66 73 50 61 67 65    aData = fsPage
40a0: 44 61 74 61 28 70 50 67 2c 20 26 6e 44 61 74 61  Data(pPg, &nData
40b0: 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 21 28  );..  assert( !(
40c0: 70 61 67 65 47 65 74 46 6c 61 67 73 28 61 44 61  pageGetFlags(aDa
40d0: 74 61 2c 20 6e 44 61 74 61 29 20 26 20 53 45 47  ta, nData) & SEG
40e0: 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 29  MENT_BTREE_FLAG)
40f0: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 69 43   );.  assert( iC
4100: 65 6c 6c 3c 70 61 67 65 47 65 74 4e 52 65 63 28  ell<pageGetNRec(
4110: 61 44 61 74 61 2c 20 6e 44 61 74 61 29 20 29 3b  aData, nData) );
4120: 0a 0a 20 20 70 4b 65 79 20 3d 20 70 61 67 65 47  ..  pKey = pageG
4130: 65 74 43 65 6c 6c 28 61 44 61 74 61 2c 20 6e 44  etCell(aData, nD
4140: 61 74 61 2c 20 69 43 65 6c 6c 29 3b 0a 20 20 65  ata, iCell);.  e
4150: 54 79 70 65 20 3d 20 2a 70 4b 65 79 2b 2b 3b 0a  Type = *pKey++;.
4160: 20 20 70 4b 65 79 20 2b 3d 20 6c 73 6d 56 61 72    pKey += lsmVar
4170: 69 6e 74 47 65 74 33 32 28 70 4b 65 79 2c 20 26  intGet32(pKey, &
4180: 6e 44 75 6d 6d 79 29 3b 0a 20 20 70 4b 65 79 20  nDummy);.  pKey 
4190: 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 47 65 74 33  += lsmVarintGet3
41a0: 32 28 70 4b 65 79 2c 20 70 6e 4b 65 79 29 3b 0a  2(pKey, pnKey);.
41b0: 20 20 69 66 28 20 72 74 49 73 57 72 69 74 65 28    if( rtIsWrite(
41c0: 65 54 79 70 65 29 20 29 7b 0a 20 20 20 20 70 4b  eType) ){.    pK
41d0: 65 79 20 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 47  ey += lsmVarintG
41e0: 65 74 33 32 28 70 4b 65 79 2c 20 26 6e 44 75 6d  et32(pKey, &nDum
41f0: 6d 79 29 3b 0a 20 20 7d 0a 20 20 2a 70 69 54 6f  my);.  }.  *piTo
4200: 70 69 63 20 3d 20 72 74 54 6f 70 69 63 28 65 54  pic = rtTopic(eT
4210: 79 70 65 29 3b 0a 0a 20 20 73 6f 72 74 65 64 52  ype);..  sortedR
4220: 65 61 64 44 61 74 61 28 70 53 65 67 2c 20 70 50  eadData(pSeg, pP
4230: 67 2c 20 70 4b 65 79 2d 61 44 61 74 61 2c 20 2a  g, pKey-aData, *
4240: 70 6e 4b 65 79 2c 20 28 76 6f 69 64 20 2a 2a 29  pnKey, (void **)
4250: 26 70 4b 65 79 2c 20 70 42 6c 6f 62 29 3b 0a 20  &pKey, pBlob);. 
4260: 20 72 65 74 75 72 6e 20 70 4b 65 79 3b 0a 7d 0a   return pKey;.}.
4270: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 61 67 65  .static int page
4280: 47 65 74 4b 65 79 43 6f 70 79 28 0a 20 20 6c 73  GetKeyCopy(.  ls
4290: 6d 5f 65 6e 76 20 2a 70 45 6e 76 2c 20 20 20 20  m_env *pEnv,    
42a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
42b0: 20 45 6e 76 69 72 6f 6e 6d 65 6e 74 20 68 61 6e   Environment han
42c0: 64 6c 65 20 2a 2f 0a 20 20 53 65 67 6d 65 6e 74  dle */.  Segment
42d0: 20 2a 70 53 65 67 2c 20 20 20 20 20 20 20 20 20   *pSeg,         
42e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 67 6d           /* Segm
42f0: 65 6e 74 20 70 50 67 20 62 65 6c 6f 6e 67 73 20  ent pPg belongs 
4300: 74 6f 20 2a 2f 0a 20 20 50 61 67 65 20 2a 70 50  to */.  Page *pP
4310: 67 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  g,              
4320: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20          /* Page 
4330: 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a  to read from */.
4340: 20 20 69 6e 74 20 69 43 65 6c 6c 2c 20 20 20 20    int iCell,    
4350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4360: 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 63 65    /* Index of ce
4370: 6c 6c 20 6f 6e 20 70 61 67 65 20 74 6f 20 72 65  ll on page to re
4380: 61 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 69 54  ad */.  int *piT
4390: 6f 70 69 63 2c 20 20 20 20 20 20 20 20 20 20 20  opic,           
43a0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
43b0: 54 6f 70 69 63 20 61 73 73 6f 63 69 61 74 65 64  Topic associated
43c0: 20 77 69 74 68 20 74 68 69 73 20 6b 65 79 20 2a   with this key *
43d0: 2f 0a 20 20 42 6c 6f 62 20 2a 70 42 6c 6f 62 20  /.  Blob *pBlob 
43e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
43f0: 20 20 20 20 2f 2a 20 49 66 20 72 65 71 75 69 72      /* If requir
4400: 65 64 2c 20 75 73 65 20 74 68 69 73 20 66 6f 72  ed, use this for
4410: 20 64 79 6e 61 6d 69 63 20 6d 65 6d 6f 72 79 20   dynamic memory 
4420: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  */.){.  int rc =
4430: 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e   LSM_OK;.  int n
4440: 4b 65 79 3b 0a 20 20 75 38 20 2a 61 4b 65 79 3b  Key;.  u8 *aKey;
4450: 0a 0a 20 20 61 4b 65 79 20 3d 20 70 61 67 65 47  ..  aKey = pageG
4460: 65 74 4b 65 79 28 70 53 65 67 2c 20 70 50 67 2c  etKey(pSeg, pPg,
4470: 20 69 43 65 6c 6c 2c 20 70 69 54 6f 70 69 63 2c   iCell, piTopic,
4480: 20 26 6e 4b 65 79 2c 20 70 42 6c 6f 62 29 3b 0a   &nKey, pBlob);.
4490: 20 20 61 73 73 65 72 74 28 20 28 76 6f 69 64 20    assert( (void 
44a0: 2a 29 61 4b 65 79 21 3d 70 42 6c 6f 62 2d 3e 70  *)aKey!=pBlob->p
44b0: 44 61 74 61 20 7c 7c 20 6e 4b 65 79 3d 3d 70 42  Data || nKey==pB
44c0: 6c 6f 62 2d 3e 6e 44 61 74 61 20 29 3b 0a 20 20  lob->nData );.  
44d0: 69 66 28 20 28 76 6f 69 64 20 2a 29 61 4b 65 79  if( (void *)aKey
44e0: 21 3d 70 42 6c 6f 62 2d 3e 70 44 61 74 61 20 29  !=pBlob->pData )
44f0: 7b 0a 20 20 20 20 72 63 20 3d 20 73 6f 72 74 65  {.    rc = sorte
4500: 64 42 6c 6f 62 53 65 74 28 70 45 6e 76 2c 20 70  dBlobSet(pEnv, p
4510: 42 6c 6f 62 2c 20 61 4b 65 79 2c 20 6e 4b 65 79  Blob, aKey, nKey
4520: 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  );.  }..  return
4530: 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 50   rc;.}..static P
4540: 67 6e 6f 20 70 61 67 65 47 65 74 42 74 72 65 65  gno pageGetBtree
4550: 52 65 66 28 50 61 67 65 20 2a 70 50 67 2c 20 69  Ref(Page *pPg, i
4560: 6e 74 20 69 4b 65 79 29 7b 0a 20 20 50 67 6e 6f  nt iKey){.  Pgno
4570: 20 69 52 65 66 3b 0a 20 20 75 38 20 2a 61 44 61   iRef;.  u8 *aDa
4580: 74 61 3b 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b  ta;.  int nData;
4590: 0a 20 20 75 38 20 2a 61 43 65 6c 6c 3b 0a 0a 20  .  u8 *aCell;.. 
45a0: 20 61 44 61 74 61 20 3d 20 66 73 50 61 67 65 44   aData = fsPageD
45b0: 61 74 61 28 70 50 67 2c 20 26 6e 44 61 74 61 29  ata(pPg, &nData)
45c0: 3b 0a 20 20 61 43 65 6c 6c 20 3d 20 70 61 67 65  ;.  aCell = page
45d0: 47 65 74 43 65 6c 6c 28 61 44 61 74 61 2c 20 6e  GetCell(aData, n
45e0: 44 61 74 61 2c 20 69 4b 65 79 29 3b 0a 20 20 61  Data, iKey);.  a
45f0: 73 73 65 72 74 28 20 61 43 65 6c 6c 5b 30 5d 3d  ssert( aCell[0]=
4600: 3d 30 20 29 3b 0a 20 20 61 43 65 6c 6c 2b 2b 3b  =0 );.  aCell++;
4610: 0a 20 20 61 43 65 6c 6c 20 2b 3d 20 6c 73 6d 56  .  aCell += lsmV
4620: 61 72 69 6e 74 47 65 74 36 34 28 61 43 65 6c 6c  arintGet64(aCell
4630: 2c 20 26 69 52 65 66 29 3b 0a 20 20 6c 73 6d 56  , &iRef);.  lsmV
4640: 61 72 69 6e 74 47 65 74 36 34 28 61 43 65 6c 6c  arintGet64(aCell
4650: 2c 20 26 69 52 65 66 29 3b 0a 20 20 61 73 73 65  , &iRef);.  asse
4660: 72 74 28 20 69 52 65 66 3e 30 20 29 3b 0a 20 20  rt( iRef>0 );.  
4670: 72 65 74 75 72 6e 20 69 52 65 66 3b 0a 7d 0a 0a  return iRef;.}..
4680: 23 64 65 66 69 6e 65 20 47 45 54 56 41 52 49 4e  #define GETVARIN
4690: 54 36 34 28 61 2c 20 69 29 20 28 28 28 69 29 3d  T64(a, i) (((i)=
46a0: 28 28 75 38 2a 29 28 61 29 29 5b 30 5d 29 3c 3d  ((u8*)(a))[0])<=
46b0: 32 34 30 3f 31 3a 6c 73 6d 56 61 72 69 6e 74 47  240?1:lsmVarintG
46c0: 65 74 36 34 28 28 61 29 2c 20 26 28 69 29 29 29  et64((a), &(i)))
46d0: 0a 23 64 65 66 69 6e 65 20 47 45 54 56 41 52 49  .#define GETVARI
46e0: 4e 54 33 32 28 61 2c 20 69 29 20 28 28 28 69 29  NT32(a, i) (((i)
46f0: 3d 28 28 75 38 2a 29 28 61 29 29 5b 30 5d 29 3c  =((u8*)(a))[0])<
4700: 3d 32 34 30 3f 31 3a 6c 73 6d 56 61 72 69 6e 74  =240?1:lsmVarint
4710: 47 65 74 33 32 28 28 61 29 2c 20 26 28 69 29 29  Get32((a), &(i))
4720: 29 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 70 61  )..static int pa
4730: 67 65 47 65 74 42 74 72 65 65 4b 65 79 28 0a 20  geGetBtreeKey(. 
4740: 20 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 2c 20   Segment *pSeg, 
4750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4760: 20 2f 2a 20 53 65 67 6d 65 6e 74 20 70 61 67 65   /* Segment page
4770: 20 70 50 67 20 62 65 6c 6f 6e 67 73 20 74 6f 20   pPg belongs to 
4780: 2a 2f 0a 20 20 50 61 67 65 20 2a 70 50 67 2c 0a  */.  Page *pPg,.
4790: 20 20 69 6e 74 20 69 4b 65 79 2c 20 0a 20 20 50    int iKey, .  P
47a0: 67 6e 6f 20 2a 70 69 50 74 72 2c 20 0a 20 20 69  gno *piPtr, .  i
47b0: 6e 74 20 2a 70 69 54 6f 70 69 63 2c 20 0a 20 20  nt *piTopic, .  
47c0: 76 6f 69 64 20 2a 2a 70 70 4b 65 79 2c 0a 20 20  void **ppKey,.  
47d0: 69 6e 74 20 2a 70 6e 4b 65 79 2c 0a 20 20 42 6c  int *pnKey,.  Bl
47e0: 6f 62 20 2a 70 42 6c 6f 62 0a 29 7b 0a 20 20 75  ob *pBlob.){.  u
47f0: 38 20 2a 61 44 61 74 61 3b 0a 20 20 69 6e 74 20  8 *aData;.  int 
4800: 6e 44 61 74 61 3b 0a 20 20 75 38 20 2a 61 43 65  nData;.  u8 *aCe
4810: 6c 6c 3b 0a 20 20 69 6e 74 20 65 54 79 70 65 3b  ll;.  int eType;
4820: 0a 0a 20 20 61 44 61 74 61 20 3d 20 66 73 50 61  ..  aData = fsPa
4830: 67 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44 61  geData(pPg, &nDa
4840: 74 61 29 3b 0a 20 20 61 73 73 65 72 74 28 20 53  ta);.  assert( S
4850: 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41  EGMENT_BTREE_FLA
4860: 47 20 26 20 70 61 67 65 47 65 74 46 6c 61 67 73  G & pageGetFlags
4870: 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29 20 29  (aData, nData) )
4880: 3b 0a 20 20 61 73 73 65 72 74 28 20 69 4b 65 79  ;.  assert( iKey
4890: 3e 3d 30 20 26 26 20 69 4b 65 79 3c 70 61 67 65  >=0 && iKey<page
48a0: 47 65 74 4e 52 65 63 28 61 44 61 74 61 2c 20 6e  GetNRec(aData, n
48b0: 44 61 74 61 29 20 29 3b 0a 0a 20 20 61 43 65 6c  Data) );..  aCel
48c0: 6c 20 3d 20 70 61 67 65 47 65 74 43 65 6c 6c 28  l = pageGetCell(
48d0: 61 44 61 74 61 2c 20 6e 44 61 74 61 2c 20 69 4b  aData, nData, iK
48e0: 65 79 29 3b 0a 20 20 65 54 79 70 65 20 3d 20 2a  ey);.  eType = *
48f0: 61 43 65 6c 6c 2b 2b 3b 0a 20 20 61 43 65 6c 6c  aCell++;.  aCell
4900: 20 2b 3d 20 47 45 54 56 41 52 49 4e 54 36 34 28   += GETVARINT64(
4910: 61 43 65 6c 6c 2c 20 2a 70 69 50 74 72 29 3b 0a  aCell, *piPtr);.
4920: 0a 20 20 69 66 28 20 65 54 79 70 65 3d 3d 30 20  .  if( eType==0 
4930: 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a 20  ){.    int rc;. 
4940: 20 20 20 50 67 6e 6f 20 69 52 65 66 3b 20 20 20     Pgno iRef;   
4950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4960: 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20 6f 66  * Page number of
4970: 20 72 65 66 65 72 65 6e 63 65 64 20 70 61 67 65   referenced page
4980: 20 2a 2f 0a 20 20 20 20 50 61 67 65 20 2a 70 52   */.    Page *pR
4990: 65 66 3b 0a 20 20 20 20 61 43 65 6c 6c 20 2b 3d  ef;.    aCell +=
49a0: 20 47 45 54 56 41 52 49 4e 54 36 34 28 61 43 65   GETVARINT64(aCe
49b0: 6c 6c 2c 20 69 52 65 66 29 3b 0a 20 20 20 20 72  ll, iRef);.    r
49c0: 63 20 3d 20 6c 73 6d 46 73 44 62 50 61 67 65 47  c = lsmFsDbPageG
49d0: 65 74 28 6c 73 6d 50 61 67 65 46 53 28 70 50 67  et(lsmPageFS(pPg
49e0: 29 2c 20 70 53 65 67 2c 20 69 52 65 66 2c 20 26  ), pSeg, iRef, &
49f0: 70 52 65 66 29 3b 0a 20 20 20 20 69 66 28 20 72  pRef);.    if( r
4a00: 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65 74 75  c!=LSM_OK ) retu
4a10: 72 6e 20 72 63 3b 0a 20 20 20 20 70 61 67 65 47  rn rc;.    pageG
4a20: 65 74 4b 65 79 43 6f 70 79 28 6c 73 6d 50 61 67  etKeyCopy(lsmPag
4a30: 65 45 6e 76 28 70 50 67 29 2c 20 70 53 65 67 2c  eEnv(pPg), pSeg,
4a40: 20 70 52 65 66 2c 20 30 2c 20 26 65 54 79 70 65   pRef, 0, &eType
4a50: 2c 20 70 42 6c 6f 62 29 3b 0a 20 20 20 20 6c 73  , pBlob);.    ls
4a60: 6d 46 73 50 61 67 65 52 65 6c 65 61 73 65 28 70  mFsPageRelease(p
4a70: 52 65 66 29 3b 0a 20 20 20 20 2a 70 70 4b 65 79  Ref);.    *ppKey
4a80: 20 3d 20 70 42 6c 6f 62 2d 3e 70 44 61 74 61 3b   = pBlob->pData;
4a90: 0a 20 20 20 20 2a 70 6e 4b 65 79 20 3d 20 70 42  .    *pnKey = pB
4aa0: 6c 6f 62 2d 3e 6e 44 61 74 61 3b 0a 20 20 7d 65  lob->nData;.  }e
4ab0: 6c 73 65 7b 0a 20 20 20 20 61 43 65 6c 6c 20 2b  lse{.    aCell +
4ac0: 3d 20 47 45 54 56 41 52 49 4e 54 33 32 28 61 43  = GETVARINT32(aC
4ad0: 65 6c 6c 2c 20 2a 70 6e 4b 65 79 29 3b 0a 20 20  ell, *pnKey);.  
4ae0: 20 20 2a 70 70 4b 65 79 20 3d 20 61 43 65 6c 6c    *ppKey = aCell
4af0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 69 54 6f  ;.  }.  if( piTo
4b00: 70 69 63 20 29 20 2a 70 69 54 6f 70 69 63 20 3d  pic ) *piTopic =
4b10: 20 72 74 54 6f 70 69 63 28 65 54 79 70 65 29 3b   rtTopic(eType);
4b20: 0a 0a 20 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f  ..  return LSM_O
4b30: 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  K;.}..static int
4b40: 20 62 74 72 65 65 43 75 72 73 6f 72 4c 6f 61 64   btreeCursorLoad
4b50: 4b 65 79 28 42 74 72 65 65 43 75 72 73 6f 72 20  Key(BtreeCursor 
4b60: 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74 20 72 63  *pCsr){.  int rc
4b70: 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 69 66 28   = LSM_OK;.  if(
4b80: 20 70 43 73 72 2d 3e 69 50 67 3c 30 20 29 7b 0a   pCsr->iPg<0 ){.
4b90: 20 20 20 20 70 43 73 72 2d 3e 70 4b 65 79 20 3d      pCsr->pKey =
4ba0: 20 30 3b 0a 20 20 20 20 70 43 73 72 2d 3e 6e 4b   0;.    pCsr->nK
4bb0: 65 79 20 3d 20 30 3b 0a 20 20 20 20 70 43 73 72  ey = 0;.    pCsr
4bc0: 2d 3e 65 54 79 70 65 20 3d 20 30 3b 0a 20 20 7d  ->eType = 0;.  }
4bd0: 65 6c 73 65 7b 0a 20 20 20 20 50 67 6e 6f 20 64  else{.    Pgno d
4be0: 75 6d 6d 79 3b 0a 20 20 20 20 69 6e 74 20 69 50  ummy;.    int iP
4bf0: 67 20 3d 20 70 43 73 72 2d 3e 69 50 67 3b 0a 20  g = pCsr->iPg;. 
4c00: 20 20 20 69 6e 74 20 69 43 65 6c 6c 20 3d 20 70     int iCell = p
4c10: 43 73 72 2d 3e 61 50 67 5b 69 50 67 5d 2e 69 43  Csr->aPg[iPg].iC
4c20: 65 6c 6c 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  ell;.    while( 
4c30: 69 43 65 6c 6c 3c 30 20 26 26 20 28 2d 2d 69 50  iCell<0 && (--iP
4c40: 67 29 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20 69  g)>=0 ){.      i
4c50: 43 65 6c 6c 20 3d 20 70 43 73 72 2d 3e 61 50 67  Cell = pCsr->aPg
4c60: 5b 69 50 67 5d 2e 69 43 65 6c 6c 2d 31 3b 0a 20  [iPg].iCell-1;. 
4c70: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 69 50 67     }.    if( iPg
4c80: 3c 30 20 7c 7c 20 69 43 65 6c 6c 3c 30 20 29 20  <0 || iCell<0 ) 
4c90: 72 65 74 75 72 6e 20 4c 53 4d 5f 43 4f 52 52 55  return LSM_CORRU
4ca0: 50 54 5f 42 4b 50 54 3b 0a 0a 20 20 20 20 72 63  PT_BKPT;..    rc
4cb0: 20 3d 20 70 61 67 65 47 65 74 42 74 72 65 65 4b   = pageGetBtreeK
4cc0: 65 79 28 0a 20 20 20 20 20 20 20 20 70 43 73 72  ey(.        pCsr
4cd0: 2d 3e 70 53 65 67 2c 0a 20 20 20 20 20 20 20 20  ->pSeg,.        
4ce0: 70 43 73 72 2d 3e 61 50 67 5b 69 50 67 5d 2e 70  pCsr->aPg[iPg].p
4cf0: 50 61 67 65 2c 20 69 43 65 6c 6c 2c 0a 20 20 20  Page, iCell,.   
4d00: 20 20 20 20 20 26 64 75 6d 6d 79 2c 20 26 70 43       &dummy, &pC
4d10: 73 72 2d 3e 65 54 79 70 65 2c 20 26 70 43 73 72  sr->eType, &pCsr
4d20: 2d 3e 70 4b 65 79 2c 20 26 70 43 73 72 2d 3e 6e  ->pKey, &pCsr->n
4d30: 4b 65 79 2c 20 26 70 43 73 72 2d 3e 62 6c 6f 62  Key, &pCsr->blob
4d40: 0a 20 20 20 20 29 3b 0a 20 20 20 20 70 43 73 72  .    );.    pCsr
4d50: 2d 3e 65 54 79 70 65 20 7c 3d 20 4c 53 4d 5f 53  ->eType |= LSM_S
4d60: 45 50 41 52 41 54 4f 52 3b 0a 20 20 7d 0a 0a 20  EPARATOR;.  }.. 
4d70: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
4d80: 74 61 74 69 63 20 69 6e 74 20 62 74 72 65 65 43  tatic int btreeC
4d90: 75 72 73 6f 72 50 74 72 28 75 38 20 2a 61 44 61  ursorPtr(u8 *aDa
4da0: 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 2c 20 69  ta, int nData, i
4db0: 6e 74 20 69 43 65 6c 6c 29 7b 0a 20 20 69 6e 74  nt iCell){.  int
4dc0: 20 6e 43 65 6c 6c 3b 0a 0a 20 20 6e 43 65 6c 6c   nCell;..  nCell
4dd0: 20 3d 20 70 61 67 65 47 65 74 4e 52 65 63 28 61   = pageGetNRec(a
4de0: 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20  Data, nData);.  
4df0: 69 66 28 20 69 43 65 6c 6c 3e 3d 6e 43 65 6c 6c  if( iCell>=nCell
4e00: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
4e10: 61 67 65 47 65 74 50 74 72 28 61 44 61 74 61 2c  ageGetPtr(aData,
4e20: 20 6e 44 61 74 61 29 3b 0a 20 20 7d 0a 20 20 72   nData);.  }.  r
4e30: 65 74 75 72 6e 20 70 61 67 65 47 65 74 52 65 63  eturn pageGetRec
4e40: 6f 72 64 50 74 72 28 61 44 61 74 61 2c 20 6e 44  ordPtr(aData, nD
4e50: 61 74 61 2c 20 69 43 65 6c 6c 29 3b 0a 7d 0a 0a  ata, iCell);.}..
4e60: 73 74 61 74 69 63 20 69 6e 74 20 62 74 72 65 65  static int btree
4e70: 43 75 72 73 6f 72 4e 65 78 74 28 42 74 72 65 65  CursorNext(Btree
4e80: 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20  Cursor *pCsr){. 
4e90: 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
4ea0: 3b 0a 0a 20 20 42 74 72 65 65 50 67 20 2a 70 50  ;..  BtreePg *pP
4eb0: 67 20 3d 20 26 70 43 73 72 2d 3e 61 50 67 5b 70  g = &pCsr->aPg[p
4ec0: 43 73 72 2d 3e 69 50 67 5d 3b 0a 20 20 69 6e 74  Csr->iPg];.  int
4ed0: 20 6e 43 65 6c 6c 3b 20 0a 20 20 75 38 20 2a 61   nCell; .  u8 *a
4ee0: 44 61 74 61 3b 0a 20 20 69 6e 74 20 6e 44 61 74  Data;.  int nDat
4ef0: 61 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 43  a;..  assert( pC
4f00: 73 72 2d 3e 69 50 67 3e 3d 30 20 29 3b 0a 20 20  sr->iPg>=0 );.  
4f10: 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e 69 50  assert( pCsr->iP
4f20: 67 3d 3d 70 43 73 72 2d 3e 6e 44 65 70 74 68 2d  g==pCsr->nDepth-
4f30: 31 20 29 3b 0a 0a 20 20 61 44 61 74 61 20 3d 20  1 );..  aData = 
4f40: 66 73 50 61 67 65 44 61 74 61 28 70 50 67 2d 3e  fsPageData(pPg->
4f50: 70 50 61 67 65 2c 20 26 6e 44 61 74 61 29 3b 0a  pPage, &nData);.
4f60: 20 20 6e 43 65 6c 6c 20 3d 20 70 61 67 65 47 65    nCell = pageGe
4f70: 74 4e 52 65 63 28 61 44 61 74 61 2c 20 6e 44 61  tNRec(aData, nDa
4f80: 74 61 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ta);.  assert( p
4f90: 50 67 2d 3e 69 43 65 6c 6c 3c 3d 6e 43 65 6c 6c  Pg->iCell<=nCell
4fa0: 20 29 3b 0a 20 20 70 50 67 2d 3e 69 43 65 6c 6c   );.  pPg->iCell
4fb0: 2b 2b 3b 0a 20 20 69 66 28 20 70 50 67 2d 3e 69  ++;.  if( pPg->i
4fc0: 43 65 6c 6c 3d 3d 6e 43 65 6c 6c 20 29 7b 0a 20  Cell==nCell ){. 
4fd0: 20 20 20 50 67 6e 6f 20 69 4c 6f 61 64 3b 0a 0a     Pgno iLoad;..
4fe0: 20 20 20 20 2f 2a 20 55 70 20 74 6f 20 70 61 72      /* Up to par
4ff0: 65 6e 74 2e 20 2a 2f 0a 20 20 20 20 6c 73 6d 46  ent. */.    lsmF
5000: 73 50 61 67 65 52 65 6c 65 61 73 65 28 70 50 67  sPageRelease(pPg
5010: 2d 3e 70 50 61 67 65 29 3b 0a 20 20 20 20 70 50  ->pPage);.    pP
5020: 67 2d 3e 70 50 61 67 65 20 3d 20 30 3b 0a 20 20  g->pPage = 0;.  
5030: 20 20 70 43 73 72 2d 3e 69 50 67 2d 2d 3b 0a 20    pCsr->iPg--;. 
5040: 20 20 20 77 68 69 6c 65 28 20 70 43 73 72 2d 3e     while( pCsr->
5050: 69 50 67 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20  iPg>=0 ){.      
5060: 70 50 67 20 3d 20 26 70 43 73 72 2d 3e 61 50 67  pPg = &pCsr->aPg
5070: 5b 70 43 73 72 2d 3e 69 50 67 5d 3b 0a 20 20 20  [pCsr->iPg];.   
5080: 20 20 20 61 44 61 74 61 20 3d 20 66 73 50 61 67     aData = fsPag
5090: 65 44 61 74 61 28 70 50 67 2d 3e 70 50 61 67 65  eData(pPg->pPage
50a0: 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 20  , &nData);.     
50b0: 20 69 66 28 20 70 50 67 2d 3e 69 43 65 6c 6c 3c   if( pPg->iCell<
50c0: 70 61 67 65 47 65 74 4e 52 65 63 28 61 44 61 74  pageGetNRec(aDat
50d0: 61 2c 20 6e 44 61 74 61 29 20 29 20 62 72 65 61  a, nData) ) brea
50e0: 6b 3b 0a 20 20 20 20 20 20 6c 73 6d 46 73 50 61  k;.      lsmFsPa
50f0: 67 65 52 65 6c 65 61 73 65 28 70 50 67 2d 3e 70  geRelease(pPg->p
5100: 50 61 67 65 29 3b 0a 20 20 20 20 20 20 70 43 73  Page);.      pCs
5110: 72 2d 3e 69 50 67 2d 2d 3b 0a 20 20 20 20 7d 0a  r->iPg--;.    }.
5120: 0a 20 20 20 20 2f 2a 20 52 65 61 64 20 74 68 65  .    /* Read the
5130: 20 6b 65 79 20 2a 2f 0a 20 20 20 20 72 63 20 3d   key */.    rc =
5140: 20 62 74 72 65 65 43 75 72 73 6f 72 4c 6f 61 64   btreeCursorLoad
5150: 4b 65 79 28 70 43 73 72 29 3b 0a 0a 20 20 20 20  Key(pCsr);..    
5160: 2f 2a 20 55 6e 6c 65 73 73 20 74 68 65 20 63 75  /* Unless the cu
5170: 72 73 6f 72 20 69 73 20 61 74 20 45 4f 46 2c 20  rsor is at EOF, 
5180: 64 65 73 63 65 6e 64 20 74 6f 20 63 65 6c 6c 20  descend to cell 
5190: 2d 31 20 28 79 65 73 2c 20 6e 65 67 61 74 69 76  -1 (yes, negativ
51a0: 65 20 6f 6e 65 29 20 6f 66 20 0a 20 20 20 20 2a  e one) of .    *
51b0: 2a 20 74 68 65 20 6c 65 66 74 2d 6d 6f 73 74 20  * the left-most 
51c0: 6d 6f 73 74 20 64 65 73 63 65 6e 64 65 6e 74 2e  most descendent.
51d0: 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 43 73 72   */.    if( pCsr
51e0: 2d 3e 69 50 67 3e 3d 30 20 29 7b 0a 20 20 20 20  ->iPg>=0 ){.    
51f0: 20 20 70 43 73 72 2d 3e 61 50 67 5b 70 43 73 72    pCsr->aPg[pCsr
5200: 2d 3e 69 50 67 5d 2e 69 43 65 6c 6c 2b 2b 3b 0a  ->iPg].iCell++;.
5210: 0a 20 20 20 20 20 20 69 4c 6f 61 64 20 3d 20 62  .      iLoad = b
5220: 74 72 65 65 43 75 72 73 6f 72 50 74 72 28 61 44  treeCursorPtr(aD
5230: 61 74 61 2c 20 6e 44 61 74 61 2c 20 70 50 67 2d  ata, nData, pPg-
5240: 3e 69 43 65 6c 6c 29 3b 0a 20 20 20 20 20 20 64  >iCell);.      d
5250: 6f 20 7b 0a 20 20 20 20 20 20 20 20 50 61 67 65  o {.        Page
5260: 20 2a 70 4c 6f 61 64 3b 0a 20 20 20 20 20 20 20   *pLoad;.       
5270: 20 70 43 73 72 2d 3e 69 50 67 2b 2b 3b 0a 20 20   pCsr->iPg++;.  
5280: 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73        rc = lsmFs
5290: 44 62 50 61 67 65 47 65 74 28 70 43 73 72 2d 3e  DbPageGet(pCsr->
52a0: 70 46 53 2c 20 70 43 73 72 2d 3e 70 53 65 67 2c  pFS, pCsr->pSeg,
52b0: 20 69 4c 6f 61 64 2c 20 26 70 4c 6f 61 64 29 3b   iLoad, &pLoad);
52c0: 0a 20 20 20 20 20 20 20 20 70 43 73 72 2d 3e 61  .        pCsr->a
52d0: 50 67 5b 70 43 73 72 2d 3e 69 50 67 5d 2e 70 50  Pg[pCsr->iPg].pP
52e0: 61 67 65 20 3d 20 70 4c 6f 61 64 3b 0a 20 20 20  age = pLoad;.   
52f0: 20 20 20 20 20 70 43 73 72 2d 3e 61 50 67 5b 70       pCsr->aPg[p
5300: 43 73 72 2d 3e 69 50 67 5d 2e 69 43 65 6c 6c 20  Csr->iPg].iCell 
5310: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 69 66 28  = 0;.        if(
5320: 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20   rc==LSM_OK ){. 
5330: 20 20 20 20 20 20 20 20 20 69 66 28 20 70 43 73           if( pCs
5340: 72 2d 3e 69 50 67 3d 3d 28 70 43 73 72 2d 3e 6e  r->iPg==(pCsr->n
5350: 44 65 70 74 68 2d 31 29 20 29 20 62 72 65 61 6b  Depth-1) ) break
5360: 3b 0a 20 20 20 20 20 20 20 20 20 20 61 44 61 74  ;.          aDat
5370: 61 20 3d 20 66 73 50 61 67 65 44 61 74 61 28 70  a = fsPageData(p
5380: 4c 6f 61 64 2c 20 26 6e 44 61 74 61 29 3b 0a 20  Load, &nData);. 
5390: 20 20 20 20 20 20 20 20 20 69 4c 6f 61 64 20 3d           iLoad =
53a0: 20 62 74 72 65 65 43 75 72 73 6f 72 50 74 72 28   btreeCursorPtr(
53b0: 61 44 61 74 61 2c 20 6e 44 61 74 61 2c 20 30 29  aData, nData, 0)
53c0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
53d0: 20 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d 4c 53    }while( rc==LS
53e0: 4d 5f 4f 4b 20 26 26 20 70 43 73 72 2d 3e 69 50  M_OK && pCsr->iP
53f0: 67 3c 28 70 43 73 72 2d 3e 6e 44 65 70 74 68 2d  g<(pCsr->nDepth-
5400: 31 29 20 29 3b 0a 20 20 20 20 20 20 70 43 73 72  1) );.      pCsr
5410: 2d 3e 61 50 67 5b 70 43 73 72 2d 3e 69 50 67 5d  ->aPg[pCsr->iPg]
5420: 2e 69 43 65 6c 6c 20 3d 20 2d 31 3b 0a 20 20 20  .iCell = -1;.   
5430: 20 7d 0a 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20   }..  }else{.   
5440: 20 72 63 20 3d 20 62 74 72 65 65 43 75 72 73 6f   rc = btreeCurso
5450: 72 4c 6f 61 64 4b 65 79 28 70 43 73 72 29 3b 0a  rLoadKey(pCsr);.
5460: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c    }..  if( rc==L
5470: 53 4d 5f 4f 4b 20 26 26 20 70 43 73 72 2d 3e 69  SM_OK && pCsr->i
5480: 50 67 3e 3d 30 20 29 7b 0a 20 20 20 20 61 44 61  Pg>=0 ){.    aDa
5490: 74 61 20 3d 20 66 73 50 61 67 65 44 61 74 61 28  ta = fsPageData(
54a0: 70 43 73 72 2d 3e 61 50 67 5b 70 43 73 72 2d 3e  pCsr->aPg[pCsr->
54b0: 69 50 67 5d 2e 70 50 61 67 65 2c 20 26 6e 44 61  iPg].pPage, &nDa
54c0: 74 61 29 3b 0a 20 20 20 20 70 43 73 72 2d 3e 69  ta);.    pCsr->i
54d0: 50 74 72 20 3d 20 62 74 72 65 65 43 75 72 73 6f  Ptr = btreeCurso
54e0: 72 50 74 72 28 61 44 61 74 61 2c 20 6e 44 61 74  rPtr(aData, nDat
54f0: 61 2c 20 70 43 73 72 2d 3e 61 50 67 5b 70 43 73  a, pCsr->aPg[pCs
5500: 72 2d 3e 69 50 67 5d 2e 69 43 65 6c 6c 2b 31 29  r->iPg].iCell+1)
5510: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
5520: 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  rc;.}..static vo
5530: 69 64 20 62 74 72 65 65 43 75 72 73 6f 72 46 72  id btreeCursorFr
5540: 65 65 28 42 74 72 65 65 43 75 72 73 6f 72 20 2a  ee(BtreeCursor *
5550: 70 43 73 72 29 7b 0a 20 20 69 66 28 20 70 43 73  pCsr){.  if( pCs
5560: 72 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a  r ){.    int i;.
5570: 20 20 20 20 6c 73 6d 5f 65 6e 76 20 2a 70 45 6e      lsm_env *pEn
5580: 76 20 3d 20 6c 73 6d 46 73 45 6e 76 28 70 43 73  v = lsmFsEnv(pCs
5590: 72 2d 3e 70 46 53 29 3b 0a 20 20 20 20 66 6f 72  r->pFS);.    for
55a0: 28 69 3d 30 3b 20 69 3c 3d 70 43 73 72 2d 3e 69  (i=0; i<=pCsr->i
55b0: 50 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  Pg; i++){.      
55c0: 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61 73 65  lsmFsPageRelease
55d0: 28 70 43 73 72 2d 3e 61 50 67 5b 69 5d 2e 70 50  (pCsr->aPg[i].pP
55e0: 61 67 65 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  age);.    }.    
55f0: 73 6f 72 74 65 64 42 6c 6f 62 46 72 65 65 28 26  sortedBlobFree(&
5600: 70 43 73 72 2d 3e 62 6c 6f 62 29 3b 0a 20 20 20  pCsr->blob);.   
5610: 20 6c 73 6d 46 72 65 65 28 70 45 6e 76 2c 20 70   lsmFree(pEnv, p
5620: 43 73 72 2d 3e 61 50 67 29 3b 0a 20 20 20 20 6c  Csr->aPg);.    l
5630: 73 6d 46 72 65 65 28 70 45 6e 76 2c 20 70 43 73  smFree(pEnv, pCs
5640: 72 29 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69  r);.  }.}..stati
5650: 63 20 69 6e 74 20 62 74 72 65 65 43 75 72 73 6f  c int btreeCurso
5660: 72 46 69 72 73 74 28 42 74 72 65 65 43 75 72 73  rFirst(BtreeCurs
5670: 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74  or *pCsr){.  int
5680: 20 72 63 3b 0a 0a 20 20 50 61 67 65 20 2a 70 50   rc;..  Page *pP
5690: 67 20 3d 20 30 3b 0a 20 20 46 69 6c 65 53 79 73  g = 0;.  FileSys
56a0: 74 65 6d 20 2a 70 46 53 20 3d 20 70 43 73 72 2d  tem *pFS = pCsr-
56b0: 3e 70 46 53 3b 0a 20 20 69 6e 74 20 69 50 67 20  >pFS;.  int iPg 
56c0: 3d 20 70 43 73 72 2d 3e 70 53 65 67 2d 3e 69 52  = pCsr->pSeg->iR
56d0: 6f 6f 74 3b 0a 0a 20 20 64 6f 20 7b 0a 20 20 20  oot;..  do {.   
56e0: 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50 61 67   rc = lsmFsDbPag
56f0: 65 47 65 74 28 70 46 53 2c 20 70 43 73 72 2d 3e  eGet(pFS, pCsr->
5700: 70 53 65 67 2c 20 69 50 67 2c 20 26 70 50 67 29  pSeg, iPg, &pPg)
5710: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 72  ;.    assert( (r
5720: 63 3d 3d 4c 53 4d 5f 4f 4b 29 3d 3d 28 70 50 67  c==LSM_OK)==(pPg
5730: 21 3d 30 29 20 29 3b 0a 20 20 20 20 69 66 28 20  !=0) );.    if( 
5740: 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20  rc==LSM_OK ){.  
5750: 20 20 20 20 75 38 20 2a 61 44 61 74 61 3b 0a 20      u8 *aData;. 
5760: 20 20 20 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a       int nData;.
5770: 20 20 20 20 20 20 69 6e 74 20 66 6c 61 67 73 3b        int flags;
5780: 0a 0a 20 20 20 20 20 20 61 44 61 74 61 20 3d 20  ..      aData = 
5790: 66 73 50 61 67 65 44 61 74 61 28 70 50 67 2c 20  fsPageData(pPg, 
57a0: 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20 66  &nData);.      f
57b0: 6c 61 67 73 20 3d 20 70 61 67 65 47 65 74 46 6c  lags = pageGetFl
57c0: 61 67 73 28 61 44 61 74 61 2c 20 6e 44 61 74 61  ags(aData, nData
57d0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 28 66 6c  );.      if( (fl
57e0: 61 67 73 20 26 20 53 45 47 4d 45 4e 54 5f 42 54  ags & SEGMENT_BT
57f0: 52 45 45 5f 46 4c 41 47 29 3d 3d 30 20 29 20 62  REE_FLAG)==0 ) b
5800: 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 69 66 28  reak;..      if(
5810: 20 28 70 43 73 72 2d 3e 6e 44 65 70 74 68 20 25   (pCsr->nDepth %
5820: 20 38 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20   8)==0 ){.      
5830: 20 20 69 6e 74 20 6e 4e 65 77 20 3d 20 70 43 73    int nNew = pCs
5840: 72 2d 3e 6e 44 65 70 74 68 20 2b 20 38 3b 0a 20  r->nDepth + 8;. 
5850: 20 20 20 20 20 20 20 70 43 73 72 2d 3e 61 50 67         pCsr->aPg
5860: 20 3d 20 28 42 74 72 65 65 50 67 20 2a 29 6c 73   = (BtreePg *)ls
5870: 6d 52 65 61 6c 6c 6f 63 4f 72 46 72 65 65 52 63  mReallocOrFreeRc
5880: 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 73  (.            ls
5890: 6d 46 73 45 6e 76 28 70 46 53 29 2c 20 70 43 73  mFsEnv(pFS), pCs
58a0: 72 2d 3e 61 50 67 2c 20 73 69 7a 65 6f 66 28 42  r->aPg, sizeof(B
58b0: 74 72 65 65 50 67 29 20 2a 20 6e 4e 65 77 2c 20  treePg) * nNew, 
58c0: 26 72 63 0a 20 20 20 20 20 20 20 20 29 3b 0a 20  &rc.        );. 
58d0: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c         if( rc==L
58e0: 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  SM_OK ){.       
58f0: 20 20 20 6d 65 6d 73 65 74 28 26 70 43 73 72 2d     memset(&pCsr-
5900: 3e 61 50 67 5b 70 43 73 72 2d 3e 6e 44 65 70 74  >aPg[pCsr->nDept
5910: 68 5d 2c 20 30 2c 20 73 69 7a 65 6f 66 28 42 74  h], 0, sizeof(Bt
5920: 72 65 65 50 67 29 20 2a 20 38 29 3b 0a 20 20 20  reePg) * 8);.   
5930: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a       }.      }..
5940: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53        if( rc==LS
5950: 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  M_OK ){.        
5960: 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e 61 50  assert( pCsr->aP
5970: 67 5b 70 43 73 72 2d 3e 6e 44 65 70 74 68 5d 2e  g[pCsr->nDepth].
5980: 69 43 65 6c 6c 3d 3d 30 20 29 3b 0a 20 20 20 20  iCell==0 );.    
5990: 20 20 20 20 70 43 73 72 2d 3e 61 50 67 5b 70 43      pCsr->aPg[pC
59a0: 73 72 2d 3e 6e 44 65 70 74 68 5d 2e 70 50 61 67  sr->nDepth].pPag
59b0: 65 20 3d 20 70 50 67 3b 0a 20 20 20 20 20 20 20  e = pPg;.       
59c0: 20 70 43 73 72 2d 3e 6e 44 65 70 74 68 2b 2b 3b   pCsr->nDepth++;
59d0: 0a 20 20 20 20 20 20 20 20 69 50 67 20 3d 20 70  .        iPg = p
59e0: 61 67 65 47 65 74 52 65 63 6f 72 64 50 74 72 28  ageGetRecordPtr(
59f0: 61 44 61 74 61 2c 20 6e 44 61 74 61 2c 20 30 29  aData, nData, 0)
5a00: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
5a10: 20 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d 4c 53    }while( rc==LS
5a20: 4d 5f 4f 4b 20 29 3b 0a 20 20 6c 73 6d 46 73 50  M_OK );.  lsmFsP
5a30: 61 67 65 52 65 6c 65 61 73 65 28 70 50 67 29 3b  ageRelease(pPg);
5a40: 0a 20 20 70 43 73 72 2d 3e 69 50 67 20 3d 20 70  .  pCsr->iPg = p
5a50: 43 73 72 2d 3e 6e 44 65 70 74 68 2d 31 3b 0a 0a  Csr->nDepth-1;..
5a60: 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
5a70: 20 26 26 20 70 43 73 72 2d 3e 6e 44 65 70 74 68   && pCsr->nDepth
5a80: 20 29 7b 0a 20 20 20 20 70 43 73 72 2d 3e 61 50   ){.    pCsr->aP
5a90: 67 5b 70 43 73 72 2d 3e 69 50 67 5d 2e 69 43 65  g[pCsr->iPg].iCe
5aa0: 6c 6c 20 3d 20 2d 31 3b 0a 20 20 20 20 72 63 20  ll = -1;.    rc 
5ab0: 3d 20 62 74 72 65 65 43 75 72 73 6f 72 4e 65 78  = btreeCursorNex
5ac0: 74 28 70 43 73 72 29 3b 0a 20 20 7d 0a 0a 20 20  t(pCsr);.  }..  
5ad0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
5ae0: 61 74 69 63 20 76 6f 69 64 20 62 74 72 65 65 43  atic void btreeC
5af0: 75 72 73 6f 72 50 6f 73 69 74 69 6f 6e 28 42 74  ursorPosition(Bt
5b00: 72 65 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  reeCursor *pCsr,
5b10: 20 4d 65 72 67 65 49 6e 70 75 74 20 2a 70 29 7b   MergeInput *p){
5b20: 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 69 50 67  .  if( pCsr->iPg
5b30: 3e 3d 30 20 29 7b 0a 20 20 20 20 70 2d 3e 69 50  >=0 ){.    p->iP
5b40: 67 20 3d 20 6c 73 6d 46 73 50 61 67 65 4e 75 6d  g = lsmFsPageNum
5b50: 62 65 72 28 70 43 73 72 2d 3e 61 50 67 5b 70 43  ber(pCsr->aPg[pC
5b60: 73 72 2d 3e 69 50 67 5d 2e 70 50 61 67 65 29 3b  sr->iPg].pPage);
5b70: 0a 20 20 20 20 70 2d 3e 69 43 65 6c 6c 20 3d 20  .    p->iCell = 
5b80: 28 28 70 43 73 72 2d 3e 61 50 67 5b 70 43 73 72  ((pCsr->aPg[pCsr
5b90: 2d 3e 69 50 67 5d 2e 69 43 65 6c 6c 20 2b 20 31  ->iPg].iCell + 1
5ba0: 29 20 3c 3c 20 38 29 20 2b 20 70 43 73 72 2d 3e  ) << 8) + pCsr->
5bb0: 6e 44 65 70 74 68 3b 0a 20 20 7d 65 6c 73 65 7b  nDepth;.  }else{
5bc0: 0a 20 20 20 20 70 2d 3e 69 50 67 20 3d 20 30 3b  .    p->iPg = 0;
5bd0: 0a 20 20 20 20 70 2d 3e 69 43 65 6c 6c 20 3d 20  .    p->iCell = 
5be0: 30 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63  0;.  }.}..static
5bf0: 20 76 6f 69 64 20 62 74 72 65 65 43 75 72 73 6f   void btreeCurso
5c00: 72 53 70 6c 69 74 6b 65 79 28 42 74 72 65 65 43  rSplitkey(BtreeC
5c10: 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 4d 65 72  ursor *pCsr, Mer
5c20: 67 65 49 6e 70 75 74 20 2a 70 29 7b 0a 20 20 69  geInput *p){.  i
5c30: 6e 74 20 69 43 65 6c 6c 20 3d 20 70 43 73 72 2d  nt iCell = pCsr-
5c40: 3e 61 50 67 5b 70 43 73 72 2d 3e 69 50 67 5d 2e  >aPg[pCsr->iPg].
5c50: 69 43 65 6c 6c 3b 0a 20 20 69 66 28 20 69 43 65  iCell;.  if( iCe
5c60: 6c 6c 3e 3d 30 20 29 7b 0a 20 20 20 20 70 2d 3e  ll>=0 ){.    p->
5c70: 69 43 65 6c 6c 20 3d 20 69 43 65 6c 6c 3b 0a 20  iCell = iCell;. 
5c80: 20 20 20 70 2d 3e 69 50 67 20 3d 20 6c 73 6d 46     p->iPg = lsmF
5c90: 73 50 61 67 65 4e 75 6d 62 65 72 28 70 43 73 72  sPageNumber(pCsr
5ca0: 2d 3e 61 50 67 5b 70 43 73 72 2d 3e 69 50 67 5d  ->aPg[pCsr->iPg]
5cb0: 2e 70 50 61 67 65 29 3b 0a 20 20 7d 65 6c 73 65  .pPage);.  }else
5cc0: 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  {.    int i;.   
5cd0: 20 66 6f 72 28 69 3d 70 43 73 72 2d 3e 69 50 67   for(i=pCsr->iPg
5ce0: 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29 7b 0a  -1; i>=0; i--){.
5cf0: 20 20 20 20 20 20 69 66 28 20 70 43 73 72 2d 3e        if( pCsr->
5d00: 61 50 67 5b 69 5d 2e 69 43 65 6c 6c 3e 30 20 29  aPg[i].iCell>0 )
5d10: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20   break;.    }.  
5d20: 20 20 61 73 73 65 72 74 28 20 69 3e 3d 30 20 29    assert( i>=0 )
5d30: 3b 0a 20 20 20 20 70 2d 3e 69 43 65 6c 6c 20 3d  ;.    p->iCell =
5d40: 20 70 43 73 72 2d 3e 61 50 67 5b 69 5d 2e 69 43   pCsr->aPg[i].iC
5d50: 65 6c 6c 2d 31 3b 0a 20 20 20 20 70 2d 3e 69 50  ell-1;.    p->iP
5d60: 67 20 3d 20 6c 73 6d 46 73 50 61 67 65 4e 75 6d  g = lsmFsPageNum
5d70: 62 65 72 28 70 43 73 72 2d 3e 61 50 67 5b 69 5d  ber(pCsr->aPg[i]
5d80: 2e 70 50 61 67 65 29 3b 0a 20 20 7d 0a 7d 0a 0a  .pPage);.  }.}..
5d90: 73 74 61 74 69 63 20 69 6e 74 20 73 6f 72 74 65  static int sorte
5da0: 64 4b 65 79 43 6f 6d 70 61 72 65 28 0a 20 20 69  dKeyCompare(.  i
5db0: 6e 74 20 28 2a 78 43 6d 70 29 28 76 6f 69 64 20  nt (*xCmp)(void 
5dc0: 2a 2c 20 69 6e 74 2c 20 76 6f 69 64 20 2a 2c 20  *, int, void *, 
5dd0: 69 6e 74 29 2c 0a 20 20 69 6e 74 20 69 4c 68 73  int),.  int iLhs
5de0: 54 6f 70 69 63 2c 20 76 6f 69 64 20 2a 70 4c 68  Topic, void *pLh
5df0: 73 4b 65 79 2c 20 69 6e 74 20 6e 4c 68 73 4b 65  sKey, int nLhsKe
5e00: 79 2c 0a 20 20 69 6e 74 20 69 52 68 73 54 6f 70  y,.  int iRhsTop
5e10: 69 63 2c 20 76 6f 69 64 20 2a 70 52 68 73 4b 65  ic, void *pRhsKe
5e20: 79 2c 20 69 6e 74 20 6e 52 68 73 4b 65 79 0a 29  y, int nRhsKey.)
5e30: 7b 0a 20 20 69 6e 74 20 72 65 73 20 3d 20 69 4c  {.  int res = iL
5e40: 68 73 54 6f 70 69 63 20 2d 20 69 52 68 73 54 6f  hsTopic - iRhsTo
5e50: 70 69 63 3b 0a 20 20 69 66 28 20 72 65 73 3d 3d  pic;.  if( res==
5e60: 30 20 29 7b 0a 20 20 20 20 72 65 73 20 3d 20 78  0 ){.    res = x
5e70: 43 6d 70 28 70 4c 68 73 4b 65 79 2c 20 6e 4c 68  Cmp(pLhsKey, nLh
5e80: 73 4b 65 79 2c 20 70 52 68 73 4b 65 79 2c 20 6e  sKey, pRhsKey, n
5e90: 52 68 73 4b 65 79 29 3b 0a 20 20 7d 0a 20 20 72  RhsKey);.  }.  r
5ea0: 65 74 75 72 6e 20 72 65 73 3b 0a 7d 0a 0a 73 74  eturn res;.}..st
5eb0: 61 74 69 63 20 69 6e 74 20 62 74 72 65 65 43 75  atic int btreeCu
5ec0: 72 73 6f 72 52 65 73 74 6f 72 65 28 0a 20 20 42  rsorRestore(.  B
5ed0: 74 72 65 65 43 75 72 73 6f 72 20 2a 70 43 73 72  treeCursor *pCsr
5ee0: 2c 20 0a 20 20 69 6e 74 20 28 2a 78 43 6d 70 29  , .  int (*xCmp)
5ef0: 28 76 6f 69 64 20 2a 2c 20 69 6e 74 2c 20 76 6f  (void *, int, vo
5f00: 69 64 20 2a 2c 20 69 6e 74 29 2c 0a 20 20 4d 65  id *, int),.  Me
5f10: 72 67 65 49 6e 70 75 74 20 2a 70 0a 29 7b 0a 20  rgeInput *p.){. 
5f20: 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
5f30: 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 69 50 67 20  ;..  if( p->iPg 
5f40: 29 7b 0a 20 20 20 20 6c 73 6d 5f 65 6e 76 20 2a  ){.    lsm_env *
5f50: 70 45 6e 76 20 3d 20 6c 73 6d 46 73 45 6e 76 28  pEnv = lsmFsEnv(
5f60: 70 43 73 72 2d 3e 70 46 53 29 3b 0a 20 20 20 20  pCsr->pFS);.    
5f70: 69 6e 74 20 69 43 65 6c 6c 3b 20 20 20 20 20 20  int iCell;      
5f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5f90: 20 43 75 72 72 65 6e 74 20 63 65 6c 6c 20 6e 75   Current cell nu
5fa0: 6d 62 65 72 20 6f 6e 20 6c 65 61 66 20 70 61 67  mber on leaf pag
5fb0: 65 20 2a 2f 0a 20 20 20 20 50 67 6e 6f 20 69 4c  e */.    Pgno iL
5fc0: 65 61 66 3b 20 20 20 20 20 20 20 20 20 20 20 20  eaf;            
5fd0: 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e         /* Page n
5fe0: 75 6d 62 65 72 20 6f 66 20 63 75 72 72 65 6e 74  umber of current
5ff0: 20 6c 65 61 66 20 70 61 67 65 20 2a 2f 0a 20 20   leaf page */.  
6000: 20 20 69 6e 74 20 6e 44 65 70 74 68 3b 20 20 20    int nDepth;   
6010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6020: 2f 2a 20 44 65 70 74 68 20 6f 66 20 62 2d 74 72  /* Depth of b-tr
6030: 65 65 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a  ee structure */.
6040: 20 20 20 20 53 65 67 6d 65 6e 74 20 2a 70 53 65      Segment *pSe
6050: 67 20 3d 20 70 43 73 72 2d 3e 70 53 65 67 3b 0a  g = pCsr->pSeg;.
6060: 0a 20 20 20 20 2f 2a 20 44 65 63 6f 64 65 20 74  .    /* Decode t
6070: 68 65 20 4d 65 72 67 65 49 6e 70 75 74 20 73 74  he MergeInput st
6080: 72 75 63 74 75 72 65 20 2a 2f 0a 20 20 20 20 69  ructure */.    i
6090: 4c 65 61 66 20 3d 20 70 2d 3e 69 50 67 3b 0a 20  Leaf = p->iPg;. 
60a0: 20 20 20 6e 44 65 70 74 68 20 3d 20 28 70 2d 3e     nDepth = (p->
60b0: 69 43 65 6c 6c 20 26 20 30 78 30 30 46 46 29 3b  iCell & 0x00FF);
60c0: 0a 20 20 20 20 69 43 65 6c 6c 20 3d 20 28 70 2d  .    iCell = (p-
60d0: 3e 69 43 65 6c 6c 20 3e 3e 20 38 29 20 2d 20 31  >iCell >> 8) - 1
60e0: 3b 0a 0a 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61  ;..    /* Alloca
60f0: 74 65 20 74 68 65 20 42 74 72 65 65 43 75 72 73  te the BtreeCurs
6100: 6f 72 2e 61 50 67 5b 5d 20 61 72 72 61 79 20 2a  or.aPg[] array *
6110: 2f 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 43  /.    assert( pC
6120: 73 72 2d 3e 61 50 67 3d 3d 30 20 29 3b 0a 20 20  sr->aPg==0 );.  
6130: 20 20 70 43 73 72 2d 3e 61 50 67 20 3d 20 28 42    pCsr->aPg = (B
6140: 74 72 65 65 50 67 20 2a 29 6c 73 6d 4d 61 6c 6c  treePg *)lsmMall
6150: 6f 63 5a 65 72 6f 52 63 28 70 45 6e 76 2c 20 73  ocZeroRc(pEnv, s
6160: 69 7a 65 6f 66 28 42 74 72 65 65 50 67 29 20 2a  izeof(BtreePg) *
6170: 20 6e 44 65 70 74 68 2c 20 26 72 63 29 3b 0a 0a   nDepth, &rc);..
6180: 20 20 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20      /* Populate 
6190: 74 68 65 20 6c 61 73 74 20 65 6e 74 72 79 20 6f  the last entry o
61a0: 66 20 74 68 65 20 61 50 67 5b 5d 20 61 72 72 61  f the aPg[] arra
61b0: 79 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d  y */.    if( rc=
61c0: 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  =LSM_OK ){.     
61d0: 20 50 61 67 65 20 2a 2a 70 70 20 3d 20 26 70 43   Page **pp = &pC
61e0: 73 72 2d 3e 61 50 67 5b 6e 44 65 70 74 68 2d 31  sr->aPg[nDepth-1
61f0: 5d 2e 70 50 61 67 65 3b 0a 20 20 20 20 20 20 70  ].pPage;.      p
6200: 43 73 72 2d 3e 69 50 67 20 3d 20 6e 44 65 70 74  Csr->iPg = nDept
6210: 68 2d 31 3b 0a 20 20 20 20 20 20 70 43 73 72 2d  h-1;.      pCsr-
6220: 3e 6e 44 65 70 74 68 20 3d 20 6e 44 65 70 74 68  >nDepth = nDepth
6230: 3b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 61 50  ;.      pCsr->aP
6240: 67 5b 70 43 73 72 2d 3e 69 50 67 5d 2e 69 43 65  g[pCsr->iPg].iCe
6250: 6c 6c 20 3d 20 69 43 65 6c 6c 3b 0a 20 20 20 20  ll = iCell;.    
6260: 20 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50 61    rc = lsmFsDbPa
6270: 67 65 47 65 74 28 70 43 73 72 2d 3e 70 46 53 2c  geGet(pCsr->pFS,
6280: 20 70 53 65 67 2c 20 69 4c 65 61 66 2c 20 70 70   pSeg, iLeaf, pp
6290: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  );.    }..    /*
62a0: 20 50 6f 70 75 6c 61 74 65 20 61 6e 79 20 6f 74   Populate any ot
62b0: 68 65 72 20 61 50 67 5b 5d 20 61 72 72 61 79 20  her aPg[] array 
62c0: 65 6e 74 72 69 65 73 20 2a 2f 0a 20 20 20 20 69  entries */.    i
62d0: 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26  f( rc==LSM_OK &&
62e0: 20 6e 44 65 70 74 68 3e 31 20 29 7b 0a 20 20 20   nDepth>1 ){.   
62f0: 20 20 20 42 6c 6f 62 20 62 6c 6f 62 20 3d 20 7b     Blob blob = {
6300: 30 2c 30 2c 30 7d 3b 0a 20 20 20 20 20 20 76 6f  0,0,0};.      vo
6310: 69 64 20 2a 70 53 65 65 6b 3b 0a 20 20 20 20 20  id *pSeek;.     
6320: 20 69 6e 74 20 6e 53 65 65 6b 3b 0a 20 20 20 20   int nSeek;.    
6330: 20 20 69 6e 74 20 69 54 6f 70 69 63 53 65 65 6b    int iTopicSeek
6340: 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 50 67 20  ;.      int iPg 
6350: 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 74 20 69  = 0;.      int i
6360: 4c 6f 61 64 20 3d 20 70 53 65 67 2d 3e 69 52 6f  Load = pSeg->iRo
6370: 6f 74 3b 0a 20 20 20 20 20 20 50 61 67 65 20 2a  ot;.      Page *
6380: 70 50 67 20 3d 20 70 43 73 72 2d 3e 61 50 67 5b  pPg = pCsr->aPg[
6390: 6e 44 65 70 74 68 2d 31 5d 2e 70 50 61 67 65 3b  nDepth-1].pPage;
63a0: 0a 20 0a 20 20 20 20 20 20 69 66 28 20 70 61 67  . .      if( pag
63b0: 65 4f 62 6a 47 65 74 4e 52 65 63 28 70 50 67 29  eObjGetNRec(pPg)
63c0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 2f  ==0 ){.        /
63d0: 2a 20 54 68 69 73 20 63 61 6e 20 68 61 70 70 65  * This can happe
63e0: 6e 20 77 68 65 6e 20 70 50 67 20 69 73 20 74 68  n when pPg is th
63f0: 65 20 72 69 67 68 74 2d 6d 6f 73 74 20 6c 65 61  e right-most lea
6400: 66 20 69 6e 20 74 68 65 20 62 2d 74 72 65 65 2e  f in the b-tree.
6410: 0a 20 20 20 20 20 20 20 20 2a 2a 20 49 6e 20 74  .        ** In t
6420: 68 69 73 20 63 61 73 65 2c 20 73 65 74 20 74 68  his case, set th
6430: 65 20 69 54 6f 70 69 63 53 65 65 6b 2f 70 53 65  e iTopicSeek/pSe
6440: 65 6b 2f 6e 53 65 65 6b 20 6b 65 79 20 74 6f 20  ek/nSeek key to 
6450: 61 20 76 61 6c 75 65 0a 20 20 20 20 20 20 20 20  a value.        
6460: 2a 2a 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  ** greater than 
6470: 61 6e 79 20 72 65 61 6c 20 6b 65 79 2e 20 20 2a  any real key.  *
6480: 2f 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  /.        assert
6490: 28 20 69 43 65 6c 6c 3d 3d 2d 31 20 29 3b 0a 20  ( iCell==-1 );. 
64a0: 20 20 20 20 20 20 20 69 54 6f 70 69 63 53 65 65         iTopicSee
64b0: 6b 20 3d 20 31 30 30 30 3b 0a 20 20 20 20 20 20  k = 1000;.      
64c0: 20 20 70 53 65 65 6b 20 3d 20 30 3b 0a 20 20 20    pSeek = 0;.   
64d0: 20 20 20 20 20 6e 53 65 65 6b 20 3d 20 30 3b 0a       nSeek = 0;.
64e0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
64f0: 20 20 20 20 20 50 67 6e 6f 20 64 75 6d 6d 79 3b       Pgno dummy;
6500: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 61  .        rc = pa
6510: 67 65 47 65 74 42 74 72 65 65 4b 65 79 28 70 53  geGetBtreeKey(pS
6520: 65 67 2c 20 70 50 67 2c 0a 20 20 20 20 20 20 20  eg, pPg,.       
6530: 20 20 20 20 20 30 2c 20 26 64 75 6d 6d 79 2c 20       0, &dummy, 
6540: 26 69 54 6f 70 69 63 53 65 65 6b 2c 20 26 70 53  &iTopicSeek, &pS
6550: 65 65 6b 2c 20 26 6e 53 65 65 6b 2c 20 26 70 43  eek, &nSeek, &pC
6560: 73 72 2d 3e 62 6c 6f 62 0a 20 20 20 20 20 20 20  sr->blob.       
6570: 20 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20   );.      }..   
6580: 20 20 20 64 6f 20 7b 0a 20 20 20 20 20 20 20 20     do {.        
6590: 50 61 67 65 20 2a 70 50 67 3b 0a 20 20 20 20 20  Page *pPg;.     
65a0: 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50     rc = lsmFsDbP
65b0: 61 67 65 47 65 74 28 70 43 73 72 2d 3e 70 46 53  ageGet(pCsr->pFS
65c0: 2c 20 70 53 65 67 2c 20 69 4c 6f 61 64 2c 20 26  , pSeg, iLoad, &
65d0: 70 50 67 29 3b 0a 20 20 20 20 20 20 20 20 61 73  pPg);.        as
65e0: 73 65 72 74 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b  sert( rc==LSM_OK
65f0: 20 7c 7c 20 70 50 67 3d 3d 30 20 29 3b 0a 20 20   || pPg==0 );.  
6600: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53        if( rc==LS
6610: 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  M_OK ){.        
6620: 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20 20 20    u8 *aData;    
6630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6640: 20 42 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69   Buffer containi
6650: 6e 67 20 70 61 67 65 20 64 61 74 61 20 2a 2f 0a  ng page data */.
6660: 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 6e 44            int nD
6670: 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20  ata;            
6680: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
6690: 20 61 44 61 74 61 5b 5d 20 69 6e 20 62 79 74 65   aData[] in byte
66a0: 73 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 69  s */.          i
66b0: 6e 74 20 69 4d 69 6e 3b 0a 20 20 20 20 20 20 20  nt iMin;.       
66c0: 20 20 20 69 6e 74 20 69 4d 61 78 3b 0a 20 20 20     int iMax;.   
66d0: 20 20 20 20 20 20 20 69 6e 74 20 69 43 65 6c 6c         int iCell
66e0: 3b 0a 0a 20 20 20 20 20 20 20 20 20 20 61 44 61  ;..          aDa
66f0: 74 61 20 3d 20 66 73 50 61 67 65 44 61 74 61 28  ta = fsPageData(
6700: 70 50 67 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20  pPg, &nData);.  
6710: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
6720: 28 70 61 67 65 47 65 74 46 6c 61 67 73 28 61 44  (pageGetFlags(aD
6730: 61 74 61 2c 20 6e 44 61 74 61 29 20 26 20 53 45  ata, nData) & SE
6740: 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47  GMENT_BTREE_FLAG
6750: 29 20 29 3b 0a 0a 20 20 20 20 20 20 20 20 20 20  ) );..          
6760: 69 4c 6f 61 64 20 3d 20 70 61 67 65 47 65 74 50  iLoad = pageGetP
6770: 74 72 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29  tr(aData, nData)
6780: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 43 65 6c  ;.          iCel
6790: 6c 20 3d 20 70 61 67 65 47 65 74 4e 52 65 63 28  l = pageGetNRec(
67a0: 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 20 0a  aData, nData); .
67b0: 20 20 20 20 20 20 20 20 20 20 69 4d 61 78 20 3d            iMax =
67c0: 20 69 43 65 6c 6c 2d 31 3b 0a 20 20 20 20 20 20   iCell-1;.      
67d0: 20 20 20 20 69 4d 69 6e 20 3d 20 30 3b 0a 0a 20      iMin = 0;.. 
67e0: 20 20 20 20 20 20 20 20 20 77 68 69 6c 65 28 20           while( 
67f0: 69 4d 61 78 3e 3d 69 4d 69 6e 20 29 7b 0a 20 20  iMax>=iMin ){.  
6800: 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 69 54            int iT
6810: 72 79 20 3d 20 28 69 4d 69 6e 2b 69 4d 61 78 29  ry = (iMin+iMax)
6820: 2f 32 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  /2;.            
6830: 76 6f 69 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20  void *pKey; int 
6840: 6e 4b 65 79 3b 20 20 20 20 20 20 20 20 20 2f 2a  nKey;         /*
6850: 20 4b 65 79 20 66 6f 72 20 63 65 6c 6c 20 69 54   Key for cell iT
6860: 72 79 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  ry */.          
6870: 20 20 69 6e 74 20 69 54 6f 70 69 63 3b 20 20 20    int iTopic;   
6880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6890: 2f 2a 20 54 6f 70 69 63 20 66 6f 72 20 6b 65 79  /* Topic for key
68a0: 20 70 4b 65 79 54 2f 6e 4b 65 79 54 20 2a 2f 0a   pKeyT/nKeyT */.
68b0: 20 20 20 20 20 20 20 20 20 20 20 20 50 67 6e 6f              Pgno
68c0: 20 69 50 74 72 3b 20 20 20 20 20 20 20 20 20 20   iPtr;          
68d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
68e0: 6e 74 65 72 20 66 6f 72 20 63 65 6c 6c 20 69 54  nter for cell iT
68f0: 72 79 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  ry */.          
6900: 20 20 69 6e 74 20 72 65 73 3b 20 20 20 20 20 20    int res;      
6910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6920: 2f 2a 20 28 70 53 65 65 6b 20 2d 20 70 4b 65 79  /* (pSeek - pKey
6930: 54 29 20 2a 2f 0a 0a 20 20 20 20 20 20 20 20 20  T) */..         
6940: 20 20 20 72 63 20 3d 20 70 61 67 65 47 65 74 42     rc = pageGetB
6950: 74 72 65 65 4b 65 79 28 0a 20 20 20 20 20 20 20  treeKey(.       
6960: 20 20 20 20 20 20 20 20 20 70 53 65 67 2c 20 70           pSeg, p
6970: 50 67 2c 20 69 54 72 79 2c 20 26 69 50 74 72 2c  Pg, iTry, &iPtr,
6980: 20 26 69 54 6f 70 69 63 2c 20 26 70 4b 65 79 2c   &iTopic, &pKey,
6990: 20 26 6e 4b 65 79 2c 20 26 62 6c 6f 62 0a 20 20   &nKey, &blob.  
69a0: 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20            );.   
69b0: 20 20 20 20 20 20 20 20 20 69 66 28 20 72 63 21           if( rc!
69c0: 3d 4c 53 4d 5f 4f 4b 20 29 20 62 72 65 61 6b 3b  =LSM_OK ) break;
69d0: 0a 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65  ..            re
69e0: 73 20 3d 20 73 6f 72 74 65 64 4b 65 79 43 6f 6d  s = sortedKeyCom
69f0: 70 61 72 65 28 0a 20 20 20 20 20 20 20 20 20 20  pare(.          
6a00: 20 20 20 20 20 20 78 43 6d 70 2c 20 69 54 6f 70        xCmp, iTop
6a10: 69 63 53 65 65 6b 2c 20 70 53 65 65 6b 2c 20 6e  icSeek, pSeek, n
6a20: 53 65 65 6b 2c 20 69 54 6f 70 69 63 2c 20 70 4b  Seek, iTopic, pK
6a30: 65 79 2c 20 6e 4b 65 79 0a 20 20 20 20 20 20 20  ey, nKey.       
6a40: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20       );.        
6a50: 20 20 20 20 61 73 73 65 72 74 28 20 72 65 73 21      assert( res!
6a60: 3d 30 20 29 3b 0a 0a 20 20 20 20 20 20 20 20 20  =0 );..         
6a70: 20 20 20 69 66 28 20 72 65 73 3c 30 20 29 7b 0a     if( res<0 ){.
6a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 4c                iL
6a90: 6f 61 64 20 3d 20 69 50 74 72 3b 0a 20 20 20 20  oad = iPtr;.    
6aa0: 20 20 20 20 20 20 20 20 20 20 69 43 65 6c 6c 20            iCell 
6ab0: 3d 20 69 54 72 79 3b 0a 20 20 20 20 20 20 20 20  = iTry;.        
6ac0: 20 20 20 20 20 20 69 4d 61 78 20 3d 20 69 54 72        iMax = iTr
6ad0: 79 2d 31 3b 0a 20 20 20 20 20 20 20 20 20 20 20  y-1;.           
6ae0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
6af0: 20 20 20 20 20 20 69 4d 69 6e 20 3d 20 69 54 72        iMin = iTr
6b00: 79 2b 31 3b 0a 20 20 20 20 20 20 20 20 20 20 20  y+1;.           
6b10: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 0a   }.          }..
6b20: 20 20 20 20 20 20 20 20 20 20 70 43 73 72 2d 3e            pCsr->
6b30: 61 50 67 5b 69 50 67 5d 2e 70 50 61 67 65 20 3d  aPg[iPg].pPage =
6b40: 20 70 50 67 3b 0a 20 20 20 20 20 20 20 20 20 20   pPg;.          
6b50: 70 43 73 72 2d 3e 61 50 67 5b 69 50 67 5d 2e 69  pCsr->aPg[iPg].i
6b60: 43 65 6c 6c 20 3d 20 69 43 65 6c 6c 3b 0a 20 20  Cell = iCell;.  
6b70: 20 20 20 20 20 20 20 20 69 50 67 2b 2b 3b 0a 20          iPg++;. 
6b80: 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
6b90: 20 69 50 67 21 3d 6e 44 65 70 74 68 2d 31 20 0a   iPg!=nDepth-1 .
6ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7c                 |
6bb0: 7c 20 6c 73 6d 46 73 52 65 64 69 72 65 63 74 50  | lsmFsRedirectP
6bc0: 61 67 65 28 70 43 73 72 2d 3e 70 46 53 2c 20 70  age(pCsr->pFS, p
6bd0: 53 65 67 2d 3e 70 52 65 64 69 72 65 63 74 2c 20  Seg->pRedirect, 
6be0: 69 4c 6f 61 64 29 3d 3d 69 4c 65 61 66 0a 20 20  iLoad)==iLeaf.  
6bf0: 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20          );.     
6c00: 20 20 20 7d 0a 20 20 20 20 20 20 7d 77 68 69 6c     }.      }whil
6c10: 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26  e( rc==LSM_OK &&
6c20: 20 69 50 67 3c 28 6e 44 65 70 74 68 2d 31 29 20   iPg<(nDepth-1) 
6c30: 29 3b 0a 20 20 20 20 20 20 73 6f 72 74 65 64 42  );.      sortedB
6c40: 6c 6f 62 46 72 65 65 28 26 62 6c 6f 62 29 3b 0a  lobFree(&blob);.
6c50: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 4c 6f      }..    /* Lo
6c60: 61 64 20 74 68 65 20 63 75 72 72 65 6e 74 20 6b  ad the current k
6c70: 65 79 20 61 6e 64 20 70 6f 69 6e 74 65 72 20 2a  ey and pointer *
6c80: 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53  /.    if( rc==LS
6c90: 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 42 74  M_OK ){.      Bt
6ca0: 72 65 65 50 67 20 2a 70 42 74 72 65 65 50 67 3b  reePg *pBtreePg;
6cb0: 0a 20 20 20 20 20 20 75 38 20 2a 61 44 61 74 61  .      u8 *aData
6cc0: 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 44 61 74  ;.      int nDat
6cd0: 61 3b 0a 0a 20 20 20 20 20 20 70 42 74 72 65 65  a;..      pBtree
6ce0: 50 67 20 3d 20 26 70 43 73 72 2d 3e 61 50 67 5b  Pg = &pCsr->aPg[
6cf0: 70 43 73 72 2d 3e 69 50 67 5d 3b 0a 20 20 20 20  pCsr->iPg];.    
6d00: 20 20 61 44 61 74 61 20 3d 20 66 73 50 61 67 65    aData = fsPage
6d10: 44 61 74 61 28 70 42 74 72 65 65 50 67 2d 3e 70  Data(pBtreePg->p
6d20: 50 61 67 65 2c 20 26 6e 44 61 74 61 29 3b 0a 20  Page, &nData);. 
6d30: 20 20 20 20 20 70 43 73 72 2d 3e 69 50 74 72 20       pCsr->iPtr 
6d40: 3d 20 62 74 72 65 65 43 75 72 73 6f 72 50 74 72  = btreeCursorPtr
6d50: 28 61 44 61 74 61 2c 20 6e 44 61 74 61 2c 20 70  (aData, nData, p
6d60: 42 74 72 65 65 50 67 2d 3e 69 43 65 6c 6c 2b 31  BtreePg->iCell+1
6d70: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 42 74  );.      if( pBt
6d80: 72 65 65 50 67 2d 3e 69 43 65 6c 6c 3c 30 20 29  reePg->iCell<0 )
6d90: 7b 0a 20 20 20 20 20 20 20 20 50 67 6e 6f 20 64  {.        Pgno d
6da0: 75 6d 6d 79 3b 0a 20 20 20 20 20 20 20 20 69 6e  ummy;.        in
6db0: 74 20 69 3b 0a 20 20 20 20 20 20 20 20 66 6f 72  t i;.        for
6dc0: 28 69 3d 70 43 73 72 2d 3e 69 50 67 2d 31 3b 20  (i=pCsr->iPg-1; 
6dd0: 69 3e 3d 30 3b 20 69 2d 2d 29 7b 0a 20 20 20 20  i>=0; i--){.    
6de0: 20 20 20 20 20 20 69 66 28 20 70 43 73 72 2d 3e        if( pCsr->
6df0: 61 50 67 5b 69 5d 2e 69 43 65 6c 6c 3e 30 20 29  aPg[i].iCell>0 )
6e00: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
6e10: 7d 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  }.        assert
6e20: 28 20 69 3e 3d 30 20 29 3b 0a 20 20 20 20 20 20  ( i>=0 );.      
6e30: 20 20 72 63 20 3d 20 70 61 67 65 47 65 74 42 74    rc = pageGetBt
6e40: 72 65 65 4b 65 79 28 70 53 65 67 2c 0a 20 20 20  reeKey(pSeg,.   
6e50: 20 20 20 20 20 20 20 20 20 70 43 73 72 2d 3e 61           pCsr->a
6e60: 50 67 5b 69 5d 2e 70 50 61 67 65 2c 20 70 43 73  Pg[i].pPage, pCs
6e70: 72 2d 3e 61 50 67 5b 69 5d 2e 69 43 65 6c 6c 2d  r->aPg[i].iCell-
6e80: 31 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 26  1,.            &
6e90: 64 75 6d 6d 79 2c 20 26 70 43 73 72 2d 3e 65 54  dummy, &pCsr->eT
6ea0: 79 70 65 2c 20 26 70 43 73 72 2d 3e 70 4b 65 79  ype, &pCsr->pKey
6eb0: 2c 20 26 70 43 73 72 2d 3e 6e 4b 65 79 2c 20 26  , &pCsr->nKey, &
6ec0: 70 43 73 72 2d 3e 62 6c 6f 62 0a 20 20 20 20 20  pCsr->blob.     
6ed0: 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 70 43     );.        pC
6ee0: 73 72 2d 3e 65 54 79 70 65 20 7c 3d 20 4c 53 4d  sr->eType |= LSM
6ef0: 5f 53 45 50 41 52 41 54 4f 52 3b 0a 0a 20 20 20  _SEPARATOR;..   
6f00: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6f10: 20 20 72 63 20 3d 20 62 74 72 65 65 43 75 72 73    rc = btreeCurs
6f20: 6f 72 4c 6f 61 64 4b 65 79 28 70 43 73 72 29 3b  orLoadKey(pCsr);
6f30: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
6f40: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
6f50: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 62 74  }..static int bt
6f60: 72 65 65 43 75 72 73 6f 72 4e 65 77 28 0a 20 20  reeCursorNew(.  
6f70: 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 0a 20 20 53  lsm_db *pDb,.  S
6f80: 65 67 6d 65 6e 74 20 2a 70 53 65 67 2c 0a 20 20  egment *pSeg,.  
6f90: 42 74 72 65 65 43 75 72 73 6f 72 20 2a 2a 70 70  BtreeCursor **pp
6fa0: 43 73 72 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20  Csr.){.  int rc 
6fb0: 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 42 74 72 65  = LSM_OK;.  Btre
6fc0: 65 43 75 72 73 6f 72 20 2a 70 43 73 72 3b 0a 20  eCursor *pCsr;. 
6fd0: 20 0a 20 20 61 73 73 65 72 74 28 20 70 53 65 67   .  assert( pSeg
6fe0: 2d 3e 69 52 6f 6f 74 20 29 3b 0a 20 20 70 43 73  ->iRoot );.  pCs
6ff0: 72 20 3d 20 6c 73 6d 4d 61 6c 6c 6f 63 5a 65 72  r = lsmMallocZer
7000: 6f 52 63 28 70 44 62 2d 3e 70 45 6e 76 2c 20 73  oRc(pDb->pEnv, s
7010: 69 7a 65 6f 66 28 42 74 72 65 65 43 75 72 73 6f  izeof(BtreeCurso
7020: 72 29 2c 20 26 72 63 29 3b 0a 20 20 69 66 28 20  r), &rc);.  if( 
7030: 70 43 73 72 20 29 7b 0a 20 20 20 20 70 43 73 72  pCsr ){.    pCsr
7040: 2d 3e 70 46 53 20 3d 20 70 44 62 2d 3e 70 46 53  ->pFS = pDb->pFS
7050: 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 53 65 67  ;.    pCsr->pSeg
7060: 20 3d 20 70 53 65 67 3b 0a 20 20 20 20 70 43 73   = pSeg;.    pCs
7070: 72 2d 3e 69 50 67 20 3d 20 2d 31 3b 0a 20 20 7d  r->iPg = -1;.  }
7080: 0a 0a 20 20 2a 70 70 43 73 72 20 3d 20 70 43 73  ..  *ppCsr = pCs
7090: 72 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  r;.  return rc;.
70a0: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73  }..static void s
70b0: 65 67 6d 65 6e 74 50 74 72 53 65 74 50 61 67 65  egmentPtrSetPage
70c0: 28 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74  (SegmentPtr *pPt
70d0: 72 2c 20 50 61 67 65 20 2a 70 4e 65 78 74 29 7b  r, Page *pNext){
70e0: 0a 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65  .  lsmFsPageRele
70f0: 61 73 65 28 70 50 74 72 2d 3e 70 50 67 29 3b 0a  ase(pPtr->pPg);.
7100: 20 20 69 66 28 20 70 4e 65 78 74 20 29 7b 0a 20    if( pNext ){. 
7110: 20 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a 20 20     int nData;.  
7120: 20 20 75 38 20 2a 61 44 61 74 61 20 3d 20 66 73    u8 *aData = fs
7130: 50 61 67 65 44 61 74 61 28 70 4e 65 78 74 2c 20  PageData(pNext, 
7140: 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 70 50 74  &nData);.    pPt
7150: 72 2d 3e 6e 43 65 6c 6c 20 3d 20 70 61 67 65 47  r->nCell = pageG
7160: 65 74 4e 52 65 63 28 61 44 61 74 61 2c 20 6e 44  etNRec(aData, nD
7170: 61 74 61 29 3b 0a 20 20 20 20 70 50 74 72 2d 3e  ata);.    pPtr->
7180: 66 6c 61 67 73 20 3d 20 70 61 67 65 47 65 74 46  flags = pageGetF
7190: 6c 61 67 73 28 61 44 61 74 61 2c 20 6e 44 61 74  lags(aData, nDat
71a0: 61 29 3b 0a 20 20 20 20 70 50 74 72 2d 3e 69 50  a);.    pPtr->iP
71b0: 74 72 20 3d 20 70 61 67 65 47 65 74 50 74 72 28  tr = pageGetPtr(
71c0: 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20  aData, nData);. 
71d0: 20 7d 0a 20 20 70 50 74 72 2d 3e 70 50 67 20 3d   }.  pPtr->pPg =
71e0: 20 70 4e 65 78 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   pNext;.}../*.**
71f0: 20 4c 6f 61 64 20 61 20 6e 65 77 20 70 61 67 65   Load a new page
7200: 20 69 6e 74 6f 20 74 68 65 20 53 65 67 6d 65 6e   into the Segmen
7210: 74 50 74 72 20 6f 62 6a 65 63 74 20 70 50 74 72  tPtr object pPtr
7220: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
7230: 73 65 67 6d 65 6e 74 50 74 72 4c 6f 61 64 50 61  segmentPtrLoadPa
7240: 67 65 28 0a 20 20 46 69 6c 65 53 79 73 74 65 6d  ge(.  FileSystem
7250: 20 2a 70 46 53 2c 0a 20 20 53 65 67 6d 65 6e 74   *pFS,.  Segment
7260: 50 74 72 20 2a 70 50 74 72 2c 20 20 20 20 20 20  Ptr *pPtr,      
7270: 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 61 64 20          /* Load 
7280: 70 61 67 65 20 69 6e 74 6f 20 74 68 69 73 20 53  page into this S
7290: 65 67 6d 65 6e 74 50 74 72 20 6f 62 6a 65 63 74  egmentPtr object
72a0: 20 2a 2f 0a 20 20 69 6e 74 20 69 4e 65 77 20 20   */.  int iNew  
72b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
72c0: 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d       /* Page num
72d0: 62 65 72 20 6f 66 20 6e 65 77 20 70 61 67 65 20  ber of new page 
72e0: 2a 2f 0a 29 7b 0a 20 20 50 61 67 65 20 2a 70 50  */.){.  Page *pP
72f0: 67 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  g = 0;          
7300: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 65         /* The ne
7310: 77 20 70 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20  w page */.  int 
7320: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
7330: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
7340: 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 0a 20 20  turn Code */..  
7350: 72 63 20 3d 20 6c 73 6d 46 73 44 62 50 61 67 65  rc = lsmFsDbPage
7360: 47 65 74 28 70 46 53 2c 20 70 50 74 72 2d 3e 70  Get(pFS, pPtr->p
7370: 53 65 67 2c 20 69 4e 65 77 2c 20 26 70 50 67 29  Seg, iNew, &pPg)
7380: 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d  ;.  assert( rc==
7390: 4c 53 4d 5f 4f 4b 20 7c 7c 20 70 50 67 3d 3d 30  LSM_OK || pPg==0
73a0: 20 29 3b 0a 20 20 73 65 67 6d 65 6e 74 50 74 72   );.  segmentPtr
73b0: 53 65 74 50 61 67 65 28 70 50 74 72 2c 20 70 50  SetPage(pPtr, pP
73c0: 67 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63  g);..  return rc
73d0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
73e0: 73 65 67 6d 65 6e 74 50 74 72 52 65 61 64 44 61  segmentPtrReadDa
73f0: 74 61 28 0a 20 20 53 65 67 6d 65 6e 74 50 74 72  ta(.  SegmentPtr
7400: 20 2a 70 50 74 72 2c 0a 20 20 69 6e 74 20 69 4f   *pPtr,.  int iO
7410: 66 66 2c 0a 20 20 69 6e 74 20 6e 42 79 74 65 2c  ff,.  int nByte,
7420: 0a 20 20 76 6f 69 64 20 2a 2a 70 70 44 61 74 61  .  void **ppData
7430: 2c 0a 20 20 42 6c 6f 62 20 2a 70 42 6c 6f 62 0a  ,.  Blob *pBlob.
7440: 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 6f 72 74  ){.  return sort
7450: 65 64 52 65 61 64 44 61 74 61 28 70 50 74 72 2d  edReadData(pPtr-
7460: 3e 70 53 65 67 2c 20 70 50 74 72 2d 3e 70 50 67  >pSeg, pPtr->pPg
7470: 2c 20 69 4f 66 66 2c 20 6e 42 79 74 65 2c 20 70  , iOff, nByte, p
7480: 70 44 61 74 61 2c 20 70 42 6c 6f 62 29 3b 0a 7d  pData, pBlob);.}
7490: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 67  ..static int seg
74a0: 6d 65 6e 74 50 74 72 4e 65 78 74 50 61 67 65 28  mentPtrNextPage(
74b0: 0a 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70  .  SegmentPtr *p
74c0: 50 74 72 2c 20 20 20 20 20 20 20 20 20 20 20 20  Ptr,            
74d0: 20 20 2f 2a 20 4c 6f 61 64 20 70 61 67 65 20 69    /* Load page i
74e0: 6e 74 6f 20 74 68 69 73 20 53 65 67 6d 65 6e 74  nto this Segment
74f0: 50 74 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  Ptr object */.  
7500: 69 6e 74 20 65 44 69 72 20 20 20 20 20 20 20 20  int eDir        
7510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7520: 2a 20 2b 31 20 66 6f 72 20 6e 65 78 74 28 29 2c  * +1 for next(),
7530: 20 2d 31 20 66 6f 72 20 70 72 65 76 28 29 20 2a   -1 for prev() *
7540: 2f 0a 29 7b 0a 20 20 50 61 67 65 20 2a 70 4e 65  /.){.  Page *pNe
7550: 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  xt;             
7560: 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 70 61 67        /* New pag
7570: 65 20 74 6f 20 6c 6f 61 64 20 2a 2f 0a 20 20 69  e to load */.  i
7580: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
7590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
75a0: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
75b0: 0a 20 20 61 73 73 65 72 74 28 20 65 44 69 72 3d  .  assert( eDir=
75c0: 3d 31 20 7c 7c 20 65 44 69 72 3d 3d 2d 31 20 29  =1 || eDir==-1 )
75d0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 50 74 72  ;.  assert( pPtr
75e0: 2d 3e 70 50 67 20 29 3b 0a 20 20 61 73 73 65 72  ->pPg );.  asser
75f0: 74 28 20 70 50 74 72 2d 3e 70 53 65 67 20 7c 7c  t( pPtr->pSeg ||
7600: 20 65 44 69 72 3e 30 20 29 3b 0a 0a 20 20 72 63   eDir>0 );..  rc
7610: 20 3d 20 6c 73 6d 46 73 44 62 50 61 67 65 4e 65   = lsmFsDbPageNe
7620: 78 74 28 70 50 74 72 2d 3e 70 53 65 67 2c 20 70  xt(pPtr->pSeg, p
7630: 50 74 72 2d 3e 70 50 67 2c 20 65 44 69 72 2c 20  Ptr->pPg, eDir, 
7640: 26 70 4e 65 78 74 29 3b 0a 20 20 61 73 73 65 72  &pNext);.  asser
7650: 74 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 7c 7c  t( rc==LSM_OK ||
7660: 20 70 4e 65 78 74 3d 3d 30 20 29 3b 0a 20 20 73   pNext==0 );.  s
7670: 65 67 6d 65 6e 74 50 74 72 53 65 74 50 61 67 65  egmentPtrSetPage
7680: 28 70 50 74 72 2c 20 70 4e 65 78 74 29 3b 0a 20  (pPtr, pNext);. 
7690: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
76a0: 74 61 74 69 63 20 69 6e 74 20 73 65 67 6d 65 6e  tatic int segmen
76b0: 74 50 74 72 4c 6f 61 64 43 65 6c 6c 28 0a 20 20  tPtrLoadCell(.  
76c0: 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72  SegmentPtr *pPtr
76d0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
76e0: 2a 20 4c 6f 61 64 20 70 61 67 65 20 69 6e 74 6f  * Load page into
76f0: 20 74 68 69 73 20 53 65 67 6d 65 6e 74 50 74 72   this SegmentPtr
7700: 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74   object */.  int
7710: 20 69 4e 65 77 20 20 20 20 20 20 20 20 20 20 20   iNew           
7720: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
7730: 65 6c 6c 20 6e 75 6d 62 65 72 20 6f 66 20 6e 65  ell number of ne
7740: 77 20 63 65 6c 6c 20 2a 2f 0a 29 7b 0a 20 20 69  w cell */.){.  i
7750: 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a  nt rc = LSM_OK;.
7760: 20 20 69 66 28 20 70 50 74 72 2d 3e 70 50 67 20    if( pPtr->pPg 
7770: 29 7b 0a 20 20 20 20 75 38 20 2a 61 44 61 74 61  ){.    u8 *aData
7780: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
7790: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
77a0: 74 6f 20 70 61 67 65 20 64 61 74 61 20 62 75 66  to page data buf
77b0: 66 65 72 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69  fer */.    int i
77c0: 4f 66 66 3b 20 20 20 20 20 20 20 20 20 20 20 20  Off;            
77d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73           /* Offs
77e0: 65 74 20 69 6e 20 61 44 61 74 61 5b 5d 20 74 6f  et in aData[] to
77f0: 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20   read from */.  
7800: 20 20 69 6e 74 20 6e 50 67 73 7a 3b 20 20 20 20    int nPgsz;    
7810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7820: 2f 2a 20 53 69 7a 65 20 6f 66 20 70 61 67 65 20  /* Size of page 
7830: 28 61 44 61 74 61 5b 5d 29 20 69 6e 20 62 79 74  (aData[]) in byt
7840: 65 73 20 2a 2f 0a 0a 20 20 20 20 61 73 73 65 72  es */..    asser
7850: 74 28 20 69 4e 65 77 3c 70 50 74 72 2d 3e 6e 43  t( iNew<pPtr->nC
7860: 65 6c 6c 20 29 3b 0a 20 20 20 20 70 50 74 72 2d  ell );.    pPtr-
7870: 3e 69 43 65 6c 6c 20 3d 20 69 4e 65 77 3b 0a 20  >iCell = iNew;. 
7880: 20 20 20 61 44 61 74 61 20 3d 20 66 73 50 61 67     aData = fsPag
7890: 65 44 61 74 61 28 70 50 74 72 2d 3e 70 50 67 2c  eData(pPtr->pPg,
78a0: 20 26 6e 50 67 73 7a 29 3b 0a 20 20 20 20 69 4f   &nPgsz);.    iO
78b0: 66 66 20 3d 20 6c 73 6d 47 65 74 55 31 36 28 26  ff = lsmGetU16(&
78c0: 61 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f 43 45  aData[SEGMENT_CE
78d0: 4c 4c 50 54 52 5f 4f 46 46 53 45 54 28 6e 50 67  LLPTR_OFFSET(nPg
78e0: 73 7a 2c 20 70 50 74 72 2d 3e 69 43 65 6c 6c 29  sz, pPtr->iCell)
78f0: 5d 29 3b 0a 20 20 20 20 70 50 74 72 2d 3e 65 54  ]);.    pPtr->eT
7900: 79 70 65 20 3d 20 61 44 61 74 61 5b 69 4f 66 66  ype = aData[iOff
7910: 5d 3b 0a 20 20 20 20 69 4f 66 66 2b 2b 3b 0a 20  ];.    iOff++;. 
7920: 20 20 20 69 4f 66 66 20 2b 3d 20 47 45 54 56 41     iOff += GETVA
7930: 52 49 4e 54 36 34 28 26 61 44 61 74 61 5b 69 4f  RINT64(&aData[iO
7940: 66 66 5d 2c 20 70 50 74 72 2d 3e 69 50 67 50 74  ff], pPtr->iPgPt
7950: 72 29 3b 0a 20 20 20 20 69 4f 66 66 20 2b 3d 20  r);.    iOff += 
7960: 47 45 54 56 41 52 49 4e 54 33 32 28 26 61 44 61  GETVARINT32(&aDa
7970: 74 61 5b 69 4f 66 66 5d 2c 20 70 50 74 72 2d 3e  ta[iOff], pPtr->
7980: 6e 4b 65 79 29 3b 0a 20 20 20 20 69 66 28 20 72  nKey);.    if( r
7990: 74 49 73 57 72 69 74 65 28 70 50 74 72 2d 3e 65  tIsWrite(pPtr->e
79a0: 54 79 70 65 29 20 29 7b 0a 20 20 20 20 20 20 69  Type) ){.      i
79b0: 4f 66 66 20 2b 3d 20 47 45 54 56 41 52 49 4e 54  Off += GETVARINT
79c0: 33 32 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c  32(&aData[iOff],
79d0: 20 70 50 74 72 2d 3e 6e 56 61 6c 29 3b 0a 20 20   pPtr->nVal);.  
79e0: 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20    }.    assert( 
79f0: 70 50 74 72 2d 3e 6e 4b 65 79 3e 3d 30 20 29 3b  pPtr->nKey>=0 );
7a00: 0a 0a 20 20 20 20 72 63 20 3d 20 73 65 67 6d 65  ..    rc = segme
7a10: 6e 74 50 74 72 52 65 61 64 44 61 74 61 28 0a 20  ntPtrReadData(. 
7a20: 20 20 20 20 20 20 20 70 50 74 72 2c 20 69 4f 66         pPtr, iOf
7a30: 66 2c 20 70 50 74 72 2d 3e 6e 4b 65 79 2c 20 26  f, pPtr->nKey, &
7a40: 70 50 74 72 2d 3e 70 4b 65 79 2c 20 26 70 50 74  pPtr->pKey, &pPt
7a50: 72 2d 3e 62 6c 6f 62 31 0a 20 20 20 20 29 3b 0a  r->blob1.    );.
7a60: 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f      if( rc==LSM_
7a70: 4f 4b 20 26 26 20 72 74 49 73 57 72 69 74 65 28  OK && rtIsWrite(
7a80: 70 50 74 72 2d 3e 65 54 79 70 65 29 20 29 7b 0a  pPtr->eType) ){.
7a90: 20 20 20 20 20 20 72 63 20 3d 20 73 65 67 6d 65        rc = segme
7aa0: 6e 74 50 74 72 52 65 61 64 44 61 74 61 28 0a 20  ntPtrReadData(. 
7ab0: 20 20 20 20 20 20 20 20 20 70 50 74 72 2c 20 69           pPtr, i
7ac0: 4f 66 66 2b 70 50 74 72 2d 3e 6e 4b 65 79 2c 20  Off+pPtr->nKey, 
7ad0: 70 50 74 72 2d 3e 6e 56 61 6c 2c 20 26 70 50 74  pPtr->nVal, &pPt
7ae0: 72 2d 3e 70 56 61 6c 2c 20 26 70 50 74 72 2d 3e  r->pVal, &pPtr->
7af0: 62 6c 6f 62 32 0a 20 20 20 20 20 20 29 3b 0a 20  blob2.      );. 
7b00: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
7b10: 70 50 74 72 2d 3e 6e 56 61 6c 20 3d 20 30 3b 0a  pPtr->nVal = 0;.
7b20: 20 20 20 20 20 20 70 50 74 72 2d 3e 70 56 61 6c        pPtr->pVal
7b30: 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   = 0;.    }.  }.
7b40: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
7b50: 0a 0a 73 74 61 74 69 63 20 53 65 67 6d 65 6e 74  ..static Segment
7b60: 20 2a 73 6f 72 74 65 64 53 70 6c 69 74 6b 65 79   *sortedSplitkey
7b70: 53 65 67 6d 65 6e 74 28 4c 65 76 65 6c 20 2a 70  Segment(Level *p
7b80: 4c 65 76 65 6c 29 7b 0a 20 20 4d 65 72 67 65 20  Level){.  Merge 
7b90: 2a 70 4d 65 72 67 65 20 3d 20 70 4c 65 76 65 6c  *pMerge = pLevel
7ba0: 2d 3e 70 4d 65 72 67 65 3b 0a 20 20 4d 65 72 67  ->pMerge;.  Merg
7bb0: 65 49 6e 70 75 74 20 2a 70 20 3d 20 26 70 4d 65  eInput *p = &pMe
7bc0: 72 67 65 2d 3e 73 70 6c 69 74 6b 65 79 3b 0a 20  rge->splitkey;. 
7bd0: 20 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 3b 0a   Segment *pSeg;.
7be0: 20 20 69 6e 74 20 69 3b 0a 0a 20 20 66 6f 72 28    int i;..  for(
7bf0: 69 3d 30 3b 20 69 3c 70 4d 65 72 67 65 2d 3e 6e  i=0; i<pMerge->n
7c00: 49 6e 70 75 74 3b 20 69 2b 2b 29 7b 0a 20 20 20  Input; i++){.   
7c10: 20 69 66 28 20 70 2d 3e 69 50 67 3d 3d 70 4d 65   if( p->iPg==pMe
7c20: 72 67 65 2d 3e 61 49 6e 70 75 74 5b 69 5d 2e 69  rge->aInput[i].i
7c30: 50 67 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a  Pg ) break;.  }.
7c40: 20 20 69 66 28 20 70 4d 65 72 67 65 2d 3e 6e 49    if( pMerge->nI
7c50: 6e 70 75 74 3d 3d 28 70 4c 65 76 65 6c 2d 3e 6e  nput==(pLevel->n
7c60: 52 69 67 68 74 2b 31 29 20 26 26 20 69 3e 3d 28  Right+1) && i>=(
7c70: 70 4d 65 72 67 65 2d 3e 6e 49 6e 70 75 74 2d 31  pMerge->nInput-1
7c80: 29 20 29 7b 0a 20 20 20 20 70 53 65 67 20 3d 20  ) ){.    pSeg = 
7c90: 26 70 4c 65 76 65 6c 2d 3e 70 4e 65 78 74 2d 3e  &pLevel->pNext->
7ca0: 6c 68 73 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  lhs;.  }else{.  
7cb0: 20 20 70 53 65 67 20 3d 20 26 70 4c 65 76 65 6c    pSeg = &pLevel
7cc0: 2d 3e 61 52 68 73 5b 69 5d 3b 0a 20 20 7d 0a 0a  ->aRhs[i];.  }..
7cd0: 20 20 72 65 74 75 72 6e 20 70 53 65 67 3b 0a 7d    return pSeg;.}
7ce0: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 6f  ..static void so
7cf0: 72 74 65 64 53 70 6c 69 74 6b 65 79 28 6c 73 6d  rtedSplitkey(lsm
7d00: 5f 64 62 20 2a 70 44 62 2c 20 4c 65 76 65 6c 20  _db *pDb, Level 
7d10: 2a 70 4c 65 76 65 6c 2c 20 69 6e 74 20 2a 70 52  *pLevel, int *pR
7d20: 63 29 7b 0a 20 20 53 65 67 6d 65 6e 74 20 2a 70  c){.  Segment *p
7d30: 53 65 67 3b 0a 20 20 50 61 67 65 20 2a 70 50 67  Seg;.  Page *pPg
7d40: 20 3d 20 30 3b 0a 20 20 6c 73 6d 5f 65 6e 76 20   = 0;.  lsm_env 
7d50: 2a 70 45 6e 76 20 3d 20 70 44 62 2d 3e 70 45 6e  *pEnv = pDb->pEn
7d60: 76 3b 20 20 20 20 20 20 2f 2a 20 45 6e 76 69 72  v;      /* Envir
7d70: 6f 6e 6d 65 6e 74 20 68 61 6e 64 6c 65 20 2a 2f  onment handle */
7d80: 0a 20 20 69 6e 74 20 72 63 20 3d 20 2a 70 52 63  .  int rc = *pRc
7d90: 3b 0a 20 20 4d 65 72 67 65 20 2a 70 4d 65 72 67  ;.  Merge *pMerg
7da0: 65 20 3d 20 70 4c 65 76 65 6c 2d 3e 70 4d 65 72  e = pLevel->pMer
7db0: 67 65 3b 0a 0a 20 20 70 53 65 67 20 3d 20 73 6f  ge;..  pSeg = so
7dc0: 72 74 65 64 53 70 6c 69 74 6b 65 79 53 65 67 6d  rtedSplitkeySegm
7dd0: 65 6e 74 28 70 4c 65 76 65 6c 29 3b 0a 20 20 69  ent(pLevel);.  i
7de0: 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b  f( rc==LSM_OK ){
7df0: 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 44  .    rc = lsmFsD
7e00: 62 50 61 67 65 47 65 74 28 70 44 62 2d 3e 70 46  bPageGet(pDb->pF
7e10: 53 2c 20 70 53 65 67 2c 20 70 4d 65 72 67 65 2d  S, pSeg, pMerge-
7e20: 3e 73 70 6c 69 74 6b 65 79 2e 69 50 67 2c 20 26  >splitkey.iPg, &
7e30: 70 50 67 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  pPg);.  }.  if( 
7e40: 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20  rc==LSM_OK ){.  
7e50: 20 20 69 6e 74 20 69 54 6f 70 69 63 3b 0a 20 20    int iTopic;.  
7e60: 20 20 42 6c 6f 62 20 62 6c 6f 62 20 3d 20 7b 30    Blob blob = {0
7e70: 2c 20 30 2c 20 30 2c 20 30 7d 3b 0a 20 20 20 20  , 0, 0, 0};.    
7e80: 75 38 20 2a 61 44 61 74 61 3b 0a 20 20 20 20 69  u8 *aData;.    i
7e90: 6e 74 20 6e 44 61 74 61 3b 0a 20 20 0a 20 20 20  nt nData;.  .   
7ea0: 20 61 44 61 74 61 20 3d 20 6c 73 6d 46 73 50 61   aData = lsmFsPa
7eb0: 67 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44 61  geData(pPg, &nDa
7ec0: 74 61 29 3b 0a 20 20 20 20 69 66 28 20 70 61 67  ta);.    if( pag
7ed0: 65 47 65 74 46 6c 61 67 73 28 61 44 61 74 61 2c  eGetFlags(aData,
7ee0: 20 6e 44 61 74 61 29 20 26 20 53 45 47 4d 45 4e   nData) & SEGMEN
7ef0: 54 5f 42 54 52 45 45 5f 46 4c 41 47 20 29 7b 0a  T_BTREE_FLAG ){.
7f00: 20 20 20 20 20 20 76 6f 69 64 20 2a 70 4b 65 79        void *pKey
7f10: 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4b 65 79  ;.      int nKey
7f20: 3b 0a 20 20 20 20 20 20 50 67 6e 6f 20 64 75 6d  ;.      Pgno dum
7f30: 6d 79 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 70  my;.      rc = p
7f40: 61 67 65 47 65 74 42 74 72 65 65 4b 65 79 28 70  ageGetBtreeKey(p
7f50: 53 65 67 2c 0a 20 20 20 20 20 20 20 20 20 20 70  Seg,.          p
7f60: 50 67 2c 20 70 4d 65 72 67 65 2d 3e 73 70 6c 69  Pg, pMerge->spli
7f70: 74 6b 65 79 2e 69 43 65 6c 6c 2c 20 26 64 75 6d  tkey.iCell, &dum
7f80: 6d 79 2c 20 26 69 54 6f 70 69 63 2c 20 26 70 4b  my, &iTopic, &pK
7f90: 65 79 2c 20 26 6e 4b 65 79 2c 20 26 62 6c 6f 62  ey, &nKey, &blob
7fa0: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20  .      );.      
7fb0: 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26  if( rc==LSM_OK &
7fc0: 26 20 62 6c 6f 62 2e 70 44 61 74 61 21 3d 70 4b  & blob.pData!=pK
7fd0: 65 79 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63  ey ){.        rc
7fe0: 20 3d 20 73 6f 72 74 65 64 42 6c 6f 62 53 65 74   = sortedBlobSet
7ff0: 28 70 45 6e 76 2c 20 26 62 6c 6f 62 2c 20 70 4b  (pEnv, &blob, pK
8000: 65 79 2c 20 6e 4b 65 79 29 3b 0a 20 20 20 20 20  ey, nKey);.     
8010: 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20   }.    }else{.  
8020: 20 20 20 20 72 63 20 3d 20 70 61 67 65 47 65 74      rc = pageGet
8030: 4b 65 79 43 6f 70 79 28 0a 20 20 20 20 20 20 20  KeyCopy(.       
8040: 20 20 20 70 45 6e 76 2c 20 70 53 65 67 2c 20 70     pEnv, pSeg, p
8050: 50 67 2c 20 70 4d 65 72 67 65 2d 3e 73 70 6c 69  Pg, pMerge->spli
8060: 74 6b 65 79 2e 69 43 65 6c 6c 2c 20 26 69 54 6f  tkey.iCell, &iTo
8070: 70 69 63 2c 20 26 62 6c 6f 62 0a 20 20 20 20 20  pic, &blob.     
8080: 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70   );.    }..    p
8090: 4c 65 76 65 6c 2d 3e 69 53 70 6c 69 74 54 6f 70  Level->iSplitTop
80a0: 69 63 20 3d 20 69 54 6f 70 69 63 3b 0a 20 20 20  ic = iTopic;.   
80b0: 20 70 4c 65 76 65 6c 2d 3e 70 53 70 6c 69 74 4b   pLevel->pSplitK
80c0: 65 79 20 3d 20 62 6c 6f 62 2e 70 44 61 74 61 3b  ey = blob.pData;
80d0: 0a 20 20 20 20 70 4c 65 76 65 6c 2d 3e 6e 53 70  .    pLevel->nSp
80e0: 6c 69 74 4b 65 79 20 3d 20 62 6c 6f 62 2e 6e 44  litKey = blob.nD
80f0: 61 74 61 3b 0a 20 20 20 20 6c 73 6d 46 73 50 61  ata;.    lsmFsPa
8100: 67 65 52 65 6c 65 61 73 65 28 70 50 67 29 3b 0a  geRelease(pPg);.
8110: 20 20 7d 0a 0a 20 20 2a 70 52 63 20 3d 20 72 63    }..  *pRc = rc
8120: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74  ;.}../*.** Reset
8130: 20 61 20 73 65 67 6d 65 6e 74 20 63 75 72 73 6f   a segment curso
8140: 72 2e 20 41 6c 73 6f 20 66 72 65 65 20 69 74 73  r. Also free its
8150: 20 62 75 66 66 65 72 73 20 69 66 20 74 68 65 79   buffers if they
8160: 20 61 72 65 20 6e 54 68 72 65 73 68 6f 6c 64 0a   are nThreshold.
8170: 2a 2a 20 62 79 74 65 73 20 6f 72 20 6c 61 72 67  ** bytes or larg
8180: 65 72 20 69 6e 20 73 69 7a 65 2e 0a 2a 2f 0a 73  er in size..*/.s
8190: 74 61 74 69 63 20 76 6f 69 64 20 73 65 67 6d 65  tatic void segme
81a0: 6e 74 50 74 72 52 65 73 65 74 28 53 65 67 6d 65  ntPtrReset(Segme
81b0: 6e 74 50 74 72 20 2a 70 50 74 72 2c 20 69 6e 74  ntPtr *pPtr, int
81c0: 20 6e 54 68 72 65 73 68 6f 6c 64 29 7b 0a 20 20   nThreshold){.  
81d0: 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61 73 65  lsmFsPageRelease
81e0: 28 70 50 74 72 2d 3e 70 50 67 29 3b 0a 20 20 70  (pPtr->pPg);.  p
81f0: 50 74 72 2d 3e 70 50 67 20 3d 20 30 3b 0a 20 20  Ptr->pPg = 0;.  
8200: 70 50 74 72 2d 3e 6e 43 65 6c 6c 20 3d 20 30 3b  pPtr->nCell = 0;
8210: 0a 20 20 70 50 74 72 2d 3e 70 4b 65 79 20 3d 20  .  pPtr->pKey = 
8220: 30 3b 0a 20 20 70 50 74 72 2d 3e 6e 4b 65 79 20  0;.  pPtr->nKey 
8230: 3d 20 30 3b 0a 20 20 70 50 74 72 2d 3e 70 56 61  = 0;.  pPtr->pVa
8240: 6c 20 3d 20 30 3b 0a 20 20 70 50 74 72 2d 3e 6e  l = 0;.  pPtr->n
8250: 56 61 6c 20 3d 20 30 3b 0a 20 20 70 50 74 72 2d  Val = 0;.  pPtr-
8260: 3e 65 54 79 70 65 20 3d 20 30 3b 0a 20 20 70 50  >eType = 0;.  pP
8270: 74 72 2d 3e 69 43 65 6c 6c 20 3d 20 30 3b 0a 20  tr->iCell = 0;. 
8280: 20 69 66 28 20 70 50 74 72 2d 3e 62 6c 6f 62 31   if( pPtr->blob1
8290: 2e 6e 41 6c 6c 6f 63 3e 3d 6e 54 68 72 65 73 68  .nAlloc>=nThresh
82a0: 6f 6c 64 20 29 20 73 6f 72 74 65 64 42 6c 6f 62  old ) sortedBlob
82b0: 46 72 65 65 28 26 70 50 74 72 2d 3e 62 6c 6f 62  Free(&pPtr->blob
82c0: 31 29 3b 0a 20 20 69 66 28 20 70 50 74 72 2d 3e  1);.  if( pPtr->
82d0: 62 6c 6f 62 32 2e 6e 41 6c 6c 6f 63 3e 3d 6e 54  blob2.nAlloc>=nT
82e0: 68 72 65 73 68 6f 6c 64 20 29 20 73 6f 72 74 65  hreshold ) sorte
82f0: 64 42 6c 6f 62 46 72 65 65 28 26 70 50 74 72 2d  dBlobFree(&pPtr-
8300: 3e 62 6c 6f 62 32 29 3b 0a 7d 0a 0a 73 74 61 74  >blob2);.}..stat
8310: 69 63 20 69 6e 74 20 73 65 67 6d 65 6e 74 50 74  ic int segmentPt
8320: 72 49 67 6e 6f 72 65 53 65 70 61 72 61 74 6f 72  rIgnoreSeparator
8330: 73 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70  s(MultiCursor *p
8340: 43 73 72 2c 20 53 65 67 6d 65 6e 74 50 74 72 20  Csr, SegmentPtr 
8350: 2a 70 50 74 72 29 7b 0a 20 20 72 65 74 75 72 6e  *pPtr){.  return
8360: 20 28 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20   (pCsr->flags & 
8370: 43 55 52 53 4f 52 5f 52 45 41 44 5f 53 45 50 41  CURSOR_READ_SEPA
8380: 52 41 54 4f 52 53 29 3d 3d 30 0a 20 20 20 20 20  RATORS)==0.     
8390: 20 7c 7c 20 28 70 50 74 72 21 3d 26 70 43 73 72   || (pPtr!=&pCsr
83a0: 2d 3e 61 50 74 72 5b 70 43 73 72 2d 3e 6e 50 74  ->aPtr[pCsr->nPt
83b0: 72 2d 31 5d 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  r-1]);.}..static
83c0: 20 69 6e 74 20 73 65 67 6d 65 6e 74 50 74 72 41   int segmentPtrA
83d0: 64 76 61 6e 63 65 28 0a 20 20 4d 75 6c 74 69 43  dvance(.  MultiC
83e0: 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 0a 20 20  ursor *pCsr, .  
83f0: 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72  SegmentPtr *pPtr
8400: 2c 0a 20 20 69 6e 74 20 62 52 65 76 65 72 73 65  ,.  int bReverse
8410: 0a 29 7b 0a 20 20 69 6e 74 20 65 44 69 72 20 3d  .){.  int eDir =
8420: 20 28 62 52 65 76 65 72 73 65 20 3f 20 2d 31 20   (bReverse ? -1 
8430: 3a 20 31 29 3b 0a 20 20 4c 65 76 65 6c 20 2a 70  : 1);.  Level *p
8440: 4c 76 6c 20 3d 20 70 50 74 72 2d 3e 70 4c 65 76  Lvl = pPtr->pLev
8450: 65 6c 3b 0a 20 20 64 6f 20 7b 0a 20 20 20 20 69  el;.  do {.    i
8460: 6e 74 20 72 63 3b 0a 20 20 20 20 69 6e 74 20 69  nt rc;.    int i
8470: 43 65 6c 6c 3b 20 20 20 20 20 20 20 20 20 20 20  Cell;           
8480: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
8490: 65 72 20 6f 66 20 6e 65 77 20 63 65 6c 6c 20 69  er of new cell i
84a0: 6e 20 70 61 67 65 20 2a 2f 0a 20 20 20 20 69 6e  n page */.    in
84b0: 74 20 73 76 46 6c 61 67 73 20 3d 20 30 3b 20 20  t svFlags = 0;  
84c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
84d0: 65 67 6d 65 6e 74 50 74 72 2e 65 54 79 70 65 20  egmentPtr.eType 
84e0: 62 65 66 6f 72 65 20 61 64 76 61 6e 63 65 20 2a  before advance *
84f0: 2f 0a 0a 20 20 20 20 69 43 65 6c 6c 20 3d 20 70  /..    iCell = p
8500: 50 74 72 2d 3e 69 43 65 6c 6c 20 2b 20 65 44 69  Ptr->iCell + eDi
8510: 72 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  r;.    assert( p
8520: 50 74 72 2d 3e 70 50 67 20 29 3b 0a 20 20 20 20  Ptr->pPg );.    
8530: 61 73 73 65 72 74 28 20 69 43 65 6c 6c 3c 3d 70  assert( iCell<=p
8540: 50 74 72 2d 3e 6e 43 65 6c 6c 20 26 26 20 69 43  Ptr->nCell && iC
8550: 65 6c 6c 3e 3d 2d 31 20 29 3b 0a 0a 20 20 20 20  ell>=-1 );..    
8560: 69 66 28 20 62 52 65 76 65 72 73 65 20 26 26 20  if( bReverse && 
8570: 70 50 74 72 2d 3e 70 53 65 67 21 3d 26 70 50 74  pPtr->pSeg!=&pPt
8580: 72 2d 3e 70 4c 65 76 65 6c 2d 3e 6c 68 73 20 29  r->pLevel->lhs )
8590: 7b 0a 20 20 20 20 20 20 73 76 46 6c 61 67 73 20  {.      svFlags 
85a0: 3d 20 70 50 74 72 2d 3e 65 54 79 70 65 3b 0a 20  = pPtr->eType;. 
85b0: 20 20 20 20 20 61 73 73 65 72 74 28 20 73 76 46       assert( svF
85c0: 6c 61 67 73 20 29 3b 0a 20 20 20 20 7d 0a 0a 20  lags );.    }.. 
85d0: 20 20 20 69 66 28 20 69 43 65 6c 6c 3e 3d 70 50     if( iCell>=pP
85e0: 74 72 2d 3e 6e 43 65 6c 6c 20 7c 7c 20 69 43 65  tr->nCell || iCe
85f0: 6c 6c 3c 30 20 29 7b 0a 20 20 20 20 20 20 64 6f  ll<0 ){.      do
8600: 20 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20   {.        rc = 
8610: 73 65 67 6d 65 6e 74 50 74 72 4e 65 78 74 50 61  segmentPtrNextPa
8620: 67 65 28 70 50 74 72 2c 20 65 44 69 72 29 3b 20  ge(pPtr, eDir); 
8630: 0a 20 20 20 20 20 20 7d 77 68 69 6c 65 28 20 72  .      }while( r
8640: 63 3d 3d 4c 53 4d 5f 4f 4b 20 0a 20 20 20 20 20  c==LSM_OK .     
8650: 20 20 20 20 20 20 26 26 20 70 50 74 72 2d 3e 70        && pPtr->p
8660: 50 67 20 0a 20 20 20 20 20 20 20 20 20 20 20 26  Pg .           &
8670: 26 20 28 70 50 74 72 2d 3e 6e 43 65 6c 6c 3d 3d  & (pPtr->nCell==
8680: 30 20 7c 7c 20 28 70 50 74 72 2d 3e 66 6c 61 67  0 || (pPtr->flag
8690: 73 20 26 20 53 45 47 4d 45 4e 54 5f 42 54 52 45  s & SEGMENT_BTRE
86a0: 45 5f 46 4c 41 47 29 20 29 20 0a 20 20 20 20 20  E_FLAG) ) .     
86b0: 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63   );.      if( rc
86c0: 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65 74 75 72  !=LSM_OK ) retur
86d0: 6e 20 72 63 3b 0a 20 20 20 20 20 20 69 43 65 6c  n rc;.      iCel
86e0: 6c 20 3d 20 62 52 65 76 65 72 73 65 20 3f 20 28  l = bReverse ? (
86f0: 70 50 74 72 2d 3e 6e 43 65 6c 6c 2d 31 29 20 3a  pPtr->nCell-1) :
8700: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63   0;.    }.    rc
8710: 20 3d 20 73 65 67 6d 65 6e 74 50 74 72 4c 6f 61   = segmentPtrLoa
8720: 64 43 65 6c 6c 28 70 50 74 72 2c 20 69 43 65 6c  dCell(pPtr, iCel
8730: 6c 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  l);.    if( rc!=
8740: 4c 53 4d 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  LSM_OK ) return 
8750: 72 63 3b 0a 0a 20 20 20 20 69 66 28 20 73 76 46  rc;..    if( svF
8760: 6c 61 67 73 20 26 26 20 70 50 74 72 2d 3e 70 50  lags && pPtr->pP
8770: 67 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72  g ){.      int r
8780: 65 73 20 3d 20 73 6f 72 74 65 64 4b 65 79 43 6f  es = sortedKeyCo
8790: 6d 70 61 72 65 28 70 43 73 72 2d 3e 70 44 62 2d  mpare(pCsr->pDb-
87a0: 3e 78 43 6d 70 2c 0a 20 20 20 20 20 20 20 20 20  >xCmp,.         
87b0: 20 72 74 54 6f 70 69 63 28 70 50 74 72 2d 3e 65   rtTopic(pPtr->e
87c0: 54 79 70 65 29 2c 20 70 50 74 72 2d 3e 70 4b 65  Type), pPtr->pKe
87d0: 79 2c 20 70 50 74 72 2d 3e 6e 4b 65 79 2c 0a 20  y, pPtr->nKey,. 
87e0: 20 20 20 20 20 20 20 20 20 70 4c 76 6c 2d 3e 69           pLvl->i
87f0: 53 70 6c 69 74 54 6f 70 69 63 2c 20 70 4c 76 6c  SplitTopic, pLvl
8800: 2d 3e 70 53 70 6c 69 74 4b 65 79 2c 20 70 4c 76  ->pSplitKey, pLv
8810: 6c 2d 3e 6e 53 70 6c 69 74 4b 65 79 0a 20 20 20  l->nSplitKey.   
8820: 20 20 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20     );.      if( 
8830: 72 65 73 3c 30 20 29 20 73 65 67 6d 65 6e 74 50  res<0 ) segmentP
8840: 74 72 52 65 73 65 74 28 70 50 74 72 2c 20 4c 53  trReset(pPtr, LS
8850: 4d 5f 53 45 47 4d 45 4e 54 50 54 52 5f 46 52 45  M_SEGMENTPTR_FRE
8860: 45 5f 54 48 52 45 53 48 4f 4c 44 29 3b 0a 20 20  E_THRESHOLD);.  
8870: 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 70 50 74    }..    if( pPt
8880: 72 2d 3e 70 50 67 3d 3d 30 20 26 26 20 28 73 76  r->pPg==0 && (sv
8890: 46 6c 61 67 73 20 26 20 4c 53 4d 5f 45 4e 44 5f  Flags & LSM_END_
88a0: 44 45 4c 45 54 45 29 20 29 7b 0a 20 20 20 20 20  DELETE) ){.     
88b0: 20 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 20 3d   Segment *pSeg =
88c0: 20 70 50 74 72 2d 3e 70 53 65 67 3b 0a 20 20 20   pPtr->pSeg;.   
88d0: 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50     rc = lsmFsDbP
88e0: 61 67 65 47 65 74 28 70 43 73 72 2d 3e 70 44 62  ageGet(pCsr->pDb
88f0: 2d 3e 70 46 53 2c 20 70 53 65 67 2c 20 70 53 65  ->pFS, pSeg, pSe
8900: 67 2d 3e 69 46 69 72 73 74 2c 20 26 70 50 74 72  g->iFirst, &pPtr
8910: 2d 3e 70 50 67 29 3b 0a 20 20 20 20 20 20 69 66  ->pPg);.      if
8920: 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72  ( rc!=LSM_OK ) r
8930: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20  eturn rc;.      
8940: 70 50 74 72 2d 3e 65 54 79 70 65 20 3d 20 4c 53  pPtr->eType = LS
8950: 4d 5f 53 54 41 52 54 5f 44 45 4c 45 54 45 20 7c  M_START_DELETE |
8960: 20 4c 53 4d 5f 50 4f 49 4e 54 5f 44 45 4c 45 54   LSM_POINT_DELET
8970: 45 3b 0a 20 20 20 20 20 20 70 50 74 72 2d 3e 65  E;.      pPtr->e
8980: 54 79 70 65 20 7c 3d 20 28 70 4c 76 6c 2d 3e 69  Type |= (pLvl->i
8990: 53 70 6c 69 74 54 6f 70 69 63 20 3f 20 4c 53 4d  SplitTopic ? LSM
89a0: 5f 53 59 53 54 45 4d 4b 45 59 20 3a 20 30 29 3b  _SYSTEMKEY : 0);
89b0: 0a 20 20 20 20 20 20 70 50 74 72 2d 3e 70 4b 65  .      pPtr->pKe
89c0: 79 20 3d 20 70 4c 76 6c 2d 3e 70 53 70 6c 69 74  y = pLvl->pSplit
89d0: 4b 65 79 3b 0a 20 20 20 20 20 20 70 50 74 72 2d  Key;.      pPtr-
89e0: 3e 6e 4b 65 79 20 3d 20 70 4c 76 6c 2d 3e 6e 53  >nKey = pLvl->nS
89f0: 70 6c 69 74 4b 65 79 3b 0a 20 20 20 20 7d 0a 0a  plitKey;.    }..
8a00: 20 20 7d 77 68 69 6c 65 28 20 70 43 73 72 20 0a    }while( pCsr .
8a10: 20 20 20 20 20 20 20 26 26 20 70 50 74 72 2d 3e         && pPtr->
8a20: 70 50 67 20 0a 20 20 20 20 20 20 20 26 26 20 73  pPg .       && s
8a30: 65 67 6d 65 6e 74 50 74 72 49 67 6e 6f 72 65 53  egmentPtrIgnoreS
8a40: 65 70 61 72 61 74 6f 72 73 28 70 43 73 72 2c 20  eparators(pCsr, 
8a50: 70 50 74 72 29 0a 20 20 20 20 20 20 20 26 26 20  pPtr).       && 
8a60: 72 74 49 73 53 65 70 61 72 61 74 6f 72 28 70 50  rtIsSeparator(pP
8a70: 74 72 2d 3e 65 54 79 70 65 29 0a 20 20 29 3b 0a  tr->eType).  );.
8a80: 0a 20 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b  .  return LSM_OK
8a90: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
8aa0: 20 73 65 67 6d 65 6e 74 50 74 72 45 6e 64 50 61   segmentPtrEndPa
8ab0: 67 65 28 0a 20 20 46 69 6c 65 53 79 73 74 65 6d  ge(.  FileSystem
8ac0: 20 2a 70 46 53 2c 20 0a 20 20 53 65 67 6d 65 6e   *pFS, .  Segmen
8ad0: 74 50 74 72 20 2a 70 50 74 72 2c 20 0a 20 20 69  tPtr *pPtr, .  i
8ae0: 6e 74 20 62 4c 61 73 74 2c 20 0a 20 20 69 6e 74  nt bLast, .  int
8af0: 20 2a 70 52 63 0a 29 7b 0a 20 20 69 66 28 20 2a   *pRc.){.  if( *
8b00: 70 52 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20  pRc==LSM_OK ){. 
8b10: 20 20 20 53 65 67 6d 65 6e 74 20 2a 70 53 65 67     Segment *pSeg
8b20: 20 3d 20 70 50 74 72 2d 3e 70 53 65 67 3b 0a 20   = pPtr->pSeg;. 
8b30: 20 20 20 50 61 67 65 20 2a 70 4e 65 77 20 3d 20     Page *pNew = 
8b40: 30 3b 0a 20 20 20 20 69 66 28 20 62 4c 61 73 74  0;.    if( bLast
8b50: 20 29 7b 0a 20 20 20 20 20 20 2a 70 52 63 20 3d   ){.      *pRc =
8b60: 20 6c 73 6d 46 73 44 62 50 61 67 65 4c 61 73 74   lsmFsDbPageLast
8b70: 28 70 46 53 2c 20 70 53 65 67 2c 20 26 70 4e 65  (pFS, pSeg, &pNe
8b80: 77 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  w);.    }else{. 
8b90: 20 20 20 20 20 2a 70 52 63 20 3d 20 6c 73 6d 46       *pRc = lsmF
8ba0: 73 44 62 50 61 67 65 47 65 74 28 70 46 53 2c 20  sDbPageGet(pFS, 
8bb0: 70 53 65 67 2c 20 70 53 65 67 2d 3e 69 46 69 72  pSeg, pSeg->iFir
8bc0: 73 74 2c 20 26 70 4e 65 77 29 3b 0a 20 20 20 20  st, &pNew);.    
8bd0: 7d 0a 20 20 20 20 73 65 67 6d 65 6e 74 50 74 72  }.    segmentPtr
8be0: 53 65 74 50 61 67 65 28 70 50 74 72 2c 20 70 4e  SetPage(pPtr, pN
8bf0: 65 77 29 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a  ew);.  }.}.../*.
8c00: 2a 2a 20 54 72 79 20 74 6f 20 6d 6f 76 65 20 74  ** Try to move t
8c10: 68 65 20 73 65 67 6d 65 6e 74 20 70 6f 69 6e 74  he segment point
8c20: 65 72 20 70 61 73 73 65 64 20 61 73 20 74 68 65  er passed as the
8c30: 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74   second argument
8c40: 20 73 6f 20 74 68 61 74 20 69 74 0a 2a 2a 20 70   so that it.** p
8c50: 6f 69 6e 74 73 20 61 74 20 65 69 74 68 65 72 20  oints at either 
8c60: 74 68 65 20 66 69 72 73 74 20 28 62 4c 61 73 74  the first (bLast
8c70: 3d 3d 30 29 20 6f 72 20 6c 61 73 74 20 28 62 4c  ==0) or last (bL
8c80: 61 73 74 3d 3d 31 29 20 63 65 6c 6c 20 69 6e 20  ast==1) cell in 
8c90: 74 68 65 20 76 61 6c 69 64 0a 2a 2a 20 72 65 67  the valid.** reg
8ca0: 69 6f 6e 20 6f 66 20 74 68 65 20 73 65 67 6d 65  ion of the segme
8cb0: 6e 74 20 64 65 66 69 6e 65 64 20 62 79 20 70 50  nt defined by pP
8cc0: 74 72 2d 3e 69 46 69 72 73 74 20 61 6e 64 20 70  tr->iFirst and p
8cd0: 50 74 72 2d 3e 69 4c 61 73 74 2e 0a 2a 2a 0a 2a  Ptr->iLast..**.*
8ce0: 2a 20 52 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 20  * Return LSM_OK 
8cf0: 69 66 20 73 75 63 63 65 73 73 66 75 6c 20 6f 72  if successful or
8d00: 20 61 6e 20 6c 73 6d 20 65 72 72 6f 72 20 63 6f   an lsm error co
8d10: 64 65 20 69 66 20 73 6f 6d 65 74 68 69 6e 67 20  de if something 
8d20: 67 6f 65 73 0a 2a 2a 20 77 72 6f 6e 67 20 28 49  goes.** wrong (I
8d30: 4f 20 65 72 72 6f 72 2c 20 4f 4f 4d 20 65 74 63  O error, OOM etc
8d40: 2e 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  .)..*/.static in
8d50: 74 20 73 65 67 6d 65 6e 74 50 74 72 45 6e 64 28  t segmentPtrEnd(
8d60: 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73  MultiCursor *pCs
8d70: 72 2c 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70  r, SegmentPtr *p
8d80: 50 74 72 2c 20 69 6e 74 20 62 4c 61 73 74 29 7b  Ptr, int bLast){
8d90: 0a 20 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 20 3d  .  Level *pLvl =
8da0: 20 70 50 74 72 2d 3e 70 4c 65 76 65 6c 3b 0a 20   pPtr->pLevel;. 
8db0: 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
8dc0: 3b 0a 20 20 46 69 6c 65 53 79 73 74 65 6d 20 2a  ;.  FileSystem *
8dd0: 70 46 53 20 3d 20 70 43 73 72 2d 3e 70 44 62 2d  pFS = pCsr->pDb-
8de0: 3e 70 46 53 3b 0a 20 20 69 6e 74 20 62 49 67 6e  >pFS;.  int bIgn
8df0: 6f 72 65 3b 0a 0a 20 20 73 65 67 6d 65 6e 74 50  ore;..  segmentP
8e00: 74 72 45 6e 64 50 61 67 65 28 70 46 53 2c 20 70  trEndPage(pFS, p
8e10: 50 74 72 2c 20 62 4c 61 73 74 2c 20 26 72 63 29  Ptr, bLast, &rc)
8e20: 3b 0a 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 4c  ;.  while( rc==L
8e30: 53 4d 5f 4f 4b 20 26 26 20 70 50 74 72 2d 3e 70  SM_OK && pPtr->p
8e40: 50 67 20 0a 20 20 20 20 20 20 26 26 20 28 70 50  Pg .      && (pP
8e50: 74 72 2d 3e 6e 43 65 6c 6c 3d 3d 30 20 7c 7c 20  tr->nCell==0 || 
8e60: 28 70 50 74 72 2d 3e 66 6c 61 67 73 20 26 20 53  (pPtr->flags & S
8e70: 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41  EGMENT_BTREE_FLA
8e80: 47 29 29 0a 20 20 29 7b 0a 20 20 20 20 72 63 20  G)).  ){.    rc 
8e90: 3d 20 73 65 67 6d 65 6e 74 50 74 72 4e 65 78 74  = segmentPtrNext
8ea0: 50 61 67 65 28 70 50 74 72 2c 20 28 62 4c 61 73  Page(pPtr, (bLas
8eb0: 74 20 3f 20 2d 31 20 3a 20 31 29 29 3b 0a 20 20  t ? -1 : 1));.  
8ec0: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d  }..  if( rc==LSM
8ed0: 5f 4f 4b 20 26 26 20 70 50 74 72 2d 3e 70 50 67  _OK && pPtr->pPg
8ee0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 65 67   ){.    rc = seg
8ef0: 6d 65 6e 74 50 74 72 4c 6f 61 64 43 65 6c 6c 28  mentPtrLoadCell(
8f00: 70 50 74 72 2c 20 62 4c 61 73 74 20 3f 20 28 70  pPtr, bLast ? (p
8f10: 50 74 72 2d 3e 6e 43 65 6c 6c 2d 31 29 20 3a 20  Ptr->nCell-1) : 
8f20: 30 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  0);.    if( rc==
8f30: 4c 53 4d 5f 4f 4b 20 26 26 20 62 4c 61 73 74 20  LSM_OK && bLast 
8f40: 26 26 20 70 50 74 72 2d 3e 70 53 65 67 21 3d 26  && pPtr->pSeg!=&
8f50: 70 4c 76 6c 2d 3e 6c 68 73 20 29 7b 0a 20 20 20  pLvl->lhs ){.   
8f60: 20 20 20 69 6e 74 20 72 65 73 20 3d 20 73 6f 72     int res = sor
8f70: 74 65 64 4b 65 79 43 6f 6d 70 61 72 65 28 70 43  tedKeyCompare(pC
8f80: 73 72 2d 3e 70 44 62 2d 3e 78 43 6d 70 2c 0a 20  sr->pDb->xCmp,. 
8f90: 20 20 20 20 20 20 20 20 20 72 74 54 6f 70 69 63           rtTopic
8fa0: 28 70 50 74 72 2d 3e 65 54 79 70 65 29 2c 20 70  (pPtr->eType), p
8fb0: 50 74 72 2d 3e 70 4b 65 79 2c 20 70 50 74 72 2d  Ptr->pKey, pPtr-
8fc0: 3e 6e 4b 65 79 2c 0a 20 20 20 20 20 20 20 20 20  >nKey,.         
8fd0: 20 70 4c 76 6c 2d 3e 69 53 70 6c 69 74 54 6f 70   pLvl->iSplitTop
8fe0: 69 63 2c 20 70 4c 76 6c 2d 3e 70 53 70 6c 69 74  ic, pLvl->pSplit
8ff0: 4b 65 79 2c 20 70 4c 76 6c 2d 3e 6e 53 70 6c 69  Key, pLvl->nSpli
9000: 74 4b 65 79 0a 20 20 20 20 20 20 29 3b 0a 20 20  tKey.      );.  
9010: 20 20 20 20 69 66 28 20 72 65 73 3c 30 20 29 20      if( res<0 ) 
9020: 73 65 67 6d 65 6e 74 50 74 72 52 65 73 65 74 28  segmentPtrReset(
9030: 70 50 74 72 2c 20 4c 53 4d 5f 53 45 47 4d 45 4e  pPtr, LSM_SEGMEN
9040: 54 50 54 52 5f 46 52 45 45 5f 54 48 52 45 53 48  TPTR_FREE_THRESH
9050: 4f 4c 44 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  OLD);.    }.  }.
9060: 20 20 0a 20 20 62 49 67 6e 6f 72 65 20 3d 20 73    .  bIgnore = s
9070: 65 67 6d 65 6e 74 50 74 72 49 67 6e 6f 72 65 53  egmentPtrIgnoreS
9080: 65 70 61 72 61 74 6f 72 73 28 70 43 73 72 2c 20  eparators(pCsr, 
9090: 70 50 74 72 29 3b 0a 20 20 69 66 28 20 72 63 3d  pPtr);.  if( rc=
90a0: 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 50 74 72 2d  =LSM_OK && pPtr-
90b0: 3e 70 50 67 20 26 26 20 62 49 67 6e 6f 72 65 20  >pPg && bIgnore 
90c0: 26 26 20 72 74 49 73 53 65 70 61 72 61 74 6f 72  && rtIsSeparator
90d0: 28 70 50 74 72 2d 3e 65 54 79 70 65 29 20 29 7b  (pPtr->eType) ){
90e0: 0a 20 20 20 20 72 63 20 3d 20 73 65 67 6d 65 6e  .    rc = segmen
90f0: 74 50 74 72 41 64 76 61 6e 63 65 28 70 43 73 72  tPtrAdvance(pCsr
9100: 2c 20 70 50 74 72 2c 20 62 4c 61 73 74 29 3b 0a  , pPtr, bLast);.
9110: 20 20 7d 0a 0a 23 69 66 20 30 0a 20 20 69 66 28    }..#if 0.  if(
9120: 20 62 4c 61 73 74 20 26 26 20 72 63 3d 3d 4c 53   bLast && rc==LS
9130: 4d 5f 4f 4b 20 26 26 20 70 50 74 72 2d 3e 70 50  M_OK && pPtr->pP
9140: 67 0a 20 20 20 26 26 20 70 50 74 72 2d 3e 70 53  g.   && pPtr->pS
9150: 65 67 3d 3d 26 70 4c 76 6c 2d 3e 6c 68 73 20 0a  eg==&pLvl->lhs .
9160: 20 20 20 26 26 20 70 4c 76 6c 2d 3e 6e 52 69 67     && pLvl->nRig
9170: 68 74 20 26 26 20 28 70 50 74 72 2d 3e 65 54 79  ht && (pPtr->eTy
9180: 70 65 20 26 20 4c 53 4d 5f 53 54 41 52 54 5f 44  pe & LSM_START_D
9190: 45 4c 45 54 45 29 0a 20 20 29 7b 0a 20 20 20 20  ELETE).  ){.    
91a0: 70 50 74 72 2d 3e 69 43 65 6c 6c 2b 2b 3b 0a 20  pPtr->iCell++;. 
91b0: 20 20 20 70 50 74 72 2d 3e 65 54 79 70 65 20 3d     pPtr->eType =
91c0: 20 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45 54 45 20   LSM_END_DELETE 
91d0: 7c 20 28 70 4c 76 6c 2d 3e 69 53 70 6c 69 74 54  | (pLvl->iSplitT
91e0: 6f 70 69 63 29 3b 0a 20 20 20 20 70 50 74 72 2d  opic);.    pPtr-
91f0: 3e 70 4b 65 79 20 3d 20 70 4c 76 6c 2d 3e 70 53  >pKey = pLvl->pS
9200: 70 6c 69 74 4b 65 79 3b 0a 20 20 20 20 70 50 74  plitKey;.    pPt
9210: 72 2d 3e 6e 4b 65 79 20 3d 20 70 4c 76 6c 2d 3e  r->nKey = pLvl->
9220: 6e 53 70 6c 69 74 4b 65 79 3b 0a 20 20 20 20 70  nSplitKey;.    p
9230: 50 74 72 2d 3e 70 56 61 6c 20 3d 20 30 3b 0a 20  Ptr->pVal = 0;. 
9240: 20 20 20 70 50 74 72 2d 3e 6e 56 61 6c 20 3d 20     pPtr->nVal = 
9250: 30 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20  0;.  }.#endif.. 
9260: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
9270: 74 61 74 69 63 20 76 6f 69 64 20 73 65 67 6d 65  tatic void segme
9280: 6e 74 50 74 72 4b 65 79 28 53 65 67 6d 65 6e 74  ntPtrKey(Segment
9290: 50 74 72 20 2a 70 50 74 72 2c 20 76 6f 69 64 20  Ptr *pPtr, void 
92a0: 2a 2a 70 70 4b 65 79 2c 20 69 6e 74 20 2a 70 6e  **ppKey, int *pn
92b0: 4b 65 79 29 7b 0a 20 20 61 73 73 65 72 74 28 20  Key){.  assert( 
92c0: 70 50 74 72 2d 3e 70 50 67 20 29 3b 0a 20 20 2a  pPtr->pPg );.  *
92d0: 70 70 4b 65 79 20 3d 20 70 50 74 72 2d 3e 70 4b  ppKey = pPtr->pK
92e0: 65 79 3b 0a 20 20 2a 70 6e 4b 65 79 20 3d 20 70  ey;.  *pnKey = p
92f0: 50 74 72 2d 3e 6e 4b 65 79 3b 0a 7d 0a 0a 23 69  Ptr->nKey;.}..#i
9300: 66 20 30 20 2f 2a 20 4e 4f 54 20 55 53 45 44 20  f 0 /* NOT USED 
9310: 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a  */.static char *
9320: 6b 65 79 54 6f 53 74 72 69 6e 67 28 6c 73 6d 5f  keyToString(lsm_
9330: 65 6e 76 20 2a 70 45 6e 76 2c 20 76 6f 69 64 20  env *pEnv, void 
9340: 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79 29  *pKey, int nKey)
9350: 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 75 38 20  {.  int i;.  u8 
9360: 2a 61 4b 65 79 20 3d 20 28 75 38 20 2a 29 70 4b  *aKey = (u8 *)pK
9370: 65 79 3b 0a 20 20 63 68 61 72 20 2a 7a 52 65 74  ey;.  char *zRet
9380: 20 3d 20 28 63 68 61 72 20 2a 29 6c 73 6d 4d 61   = (char *)lsmMa
9390: 6c 6c 6f 63 28 70 45 6e 76 2c 20 6e 4b 65 79 2b  lloc(pEnv, nKey+
93a0: 31 29 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20  1);..  for(i=0; 
93b0: 69 3c 6e 4b 65 79 3b 20 69 2b 2b 29 7b 0a 20 20  i<nKey; i++){.  
93c0: 20 20 7a 52 65 74 5b 69 5d 20 3d 20 28 63 68 61    zRet[i] = (cha
93d0: 72 29 28 69 73 61 6c 6e 75 6d 28 61 4b 65 79 5b  r)(isalnum(aKey[
93e0: 69 5d 29 20 3f 20 61 4b 65 79 5b 69 5d 20 3a 20  i]) ? aKey[i] : 
93f0: 27 2e 27 29 3b 0a 20 20 7d 0a 20 20 7a 52 65 74  '.');.  }.  zRet
9400: 5b 6e 4b 65 79 5d 20 3d 20 27 5c 30 27 3b 0a 20  [nKey] = '\0';. 
9410: 20 72 65 74 75 72 6e 20 7a 52 65 74 3b 0a 7d 0a   return zRet;.}.
9420: 23 65 6e 64 69 66 0a 0a 23 69 66 20 30 20 2f 2a  #endif..#if 0 /*
9430: 20 4e 4f 54 20 55 53 45 44 20 2a 2f 0a 2f 2a 0a   NOT USED */./*.
9440: 2a 2a 20 43 68 65 63 6b 20 74 68 61 74 20 74 68  ** Check that th
9450: 65 20 70 61 67 65 20 74 68 61 74 20 70 50 74 72  e page that pPtr
9460: 20 63 75 72 72 65 6e 74 6c 79 20 68 61 73 20 6c   currently has l
9470: 6f 61 64 65 64 20 69 73 20 74 68 65 20 63 6f 72  oaded is the cor
9480: 72 65 63 74 20 70 61 67 65 0a 2a 2a 20 74 6f 20  rect page.** to 
9490: 73 65 61 72 63 68 20 66 6f 72 20 6b 65 79 20 28  search for key (
94a0: 70 4b 65 79 2f 6e 4b 65 79 29 2e 20 49 66 20 69  pKey/nKey). If i
94b0: 74 20 69 73 2c 20 72 65 74 75 72 6e 20 31 2e 20  t is, return 1. 
94c0: 4f 74 68 65 72 77 69 73 65 2c 20 61 6e 20 61 73  Otherwise, an as
94d0: 73 65 72 74 0a 2a 2a 20 66 61 69 6c 73 20 61 6e  sert.** fails an
94e0: 64 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  d this function 
94f0: 64 6f 65 73 20 6e 6f 74 20 72 65 74 75 72 6e 2e  does not return.
9500: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .*/.static int a
9510: 73 73 65 72 74 4b 65 79 4c 6f 63 61 74 69 6f 6e  ssertKeyLocation
9520: 28 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  (.  MultiCursor 
9530: 2a 70 43 73 72 2c 20 0a 20 20 53 65 67 6d 65 6e  *pCsr, .  Segmen
9540: 74 50 74 72 20 2a 70 50 74 72 2c 20 0a 20 20 76  tPtr *pPtr, .  v
9550: 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e  oid *pKey, int n
9560: 4b 65 79 0a 29 7b 0a 20 20 6c 73 6d 5f 65 6e 76  Key.){.  lsm_env
9570: 20 2a 70 45 6e 76 20 3d 20 6c 73 6d 46 73 45 6e   *pEnv = lsmFsEn
9580: 76 28 70 43 73 72 2d 3e 70 44 62 2d 3e 70 46 53  v(pCsr->pDb->pFS
9590: 29 3b 0a 20 20 42 6c 6f 62 20 62 6c 6f 62 20 3d  );.  Blob blob =
95a0: 20 7b 30 2c 20 30 2c 20 30 7d 3b 0a 20 20 69 6e   {0, 0, 0};.  in
95b0: 74 20 65 44 69 72 3b 0a 20 20 69 6e 74 20 69 54  t eDir;.  int iT
95c0: 6f 70 69 63 20 3d 20 30 3b 20 20 20 20 20 20 20  opic = 0;       
95d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 4f 44            /* TOD
95e0: 4f 3a 20 46 69 78 20 6d 65 20 2a 2f 0a 0a 20 20  O: Fix me */..  
95f0: 66 6f 72 28 65 44 69 72 3d 2d 31 3b 20 65 44 69  for(eDir=-1; eDi
9600: 72 3c 3d 31 3b 20 65 44 69 72 2b 3d 32 29 7b 0a  r<=1; eDir+=2){.
9610: 20 20 20 20 50 61 67 65 20 2a 70 54 65 73 74 20      Page *pTest 
9620: 3d 20 70 50 74 72 2d 3e 70 50 67 3b 0a 0a 20 20  = pPtr->pPg;..  
9630: 20 20 6c 73 6d 46 73 50 61 67 65 52 65 66 28 70    lsmFsPageRef(p
9640: 54 65 73 74 29 3b 0a 20 20 20 20 77 68 69 6c 65  Test);.    while
9650: 28 20 70 54 65 73 74 20 29 7b 0a 20 20 20 20 20  ( pTest ){.     
9660: 20 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 20 3d   Segment *pSeg =
9670: 20 70 50 74 72 2d 3e 70 53 65 67 3b 0a 20 20 20   pPtr->pSeg;.   
9680: 20 20 20 50 61 67 65 20 2a 70 4e 65 78 74 3b 0a     Page *pNext;.
9690: 0a 20 20 20 20 20 20 69 6e 74 20 72 63 20 3d 20  .      int rc = 
96a0: 6c 73 6d 46 73 44 62 50 61 67 65 4e 65 78 74 28  lsmFsDbPageNext(
96b0: 70 53 65 67 2c 20 70 54 65 73 74 2c 20 65 44 69  pSeg, pTest, eDi
96c0: 72 2c 20 26 70 4e 65 78 74 29 3b 0a 20 20 20 20  r, &pNext);.    
96d0: 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61    lsmFsPageRelea
96e0: 73 65 28 70 54 65 73 74 29 3b 0a 20 20 20 20 20  se(pTest);.     
96f0: 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e   if( rc ) return
9700: 20 31 3b 0a 20 20 20 20 20 20 70 54 65 73 74 20   1;.      pTest 
9710: 3d 20 70 4e 65 78 74 3b 0a 0a 20 20 20 20 20 20  = pNext;..      
9720: 69 66 28 20 70 54 65 73 74 20 29 7b 0a 20 20 20  if( pTest ){.   
9730: 20 20 20 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a       int nData;.
9740: 20 20 20 20 20 20 20 20 75 38 20 2a 61 44 61 74          u8 *aDat
9750: 61 20 3d 20 66 73 50 61 67 65 44 61 74 61 28 70  a = fsPageData(p
9760: 54 65 73 74 2c 20 26 6e 44 61 74 61 29 3b 0a 20  Test, &nData);. 
9770: 20 20 20 20 20 20 20 69 6e 74 20 6e 43 65 6c 6c         int nCell
9780: 20 3d 20 70 61 67 65 47 65 74 4e 52 65 63 28 61   = pageGetNRec(a
9790: 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20  Data, nData);.  
97a0: 20 20 20 20 20 20 69 6e 74 20 66 6c 61 67 73 20        int flags 
97b0: 3d 20 70 61 67 65 47 65 74 46 6c 61 67 73 28 61  = pageGetFlags(a
97c0: 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20  Data, nData);.  
97d0: 20 20 20 20 20 20 69 66 28 20 6e 43 65 6c 6c 20        if( nCell 
97e0: 26 26 20 30 3d 3d 28 66 6c 61 67 73 26 53 45 47  && 0==(flags&SEG
97f0: 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 29  MENT_BTREE_FLAG)
9800: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 6e   ){.          in
9810: 74 20 6e 50 67 4b 65 79 3b 0a 20 20 20 20 20 20  t nPgKey;.      
9820: 20 20 20 20 69 6e 74 20 69 50 67 54 6f 70 69 63      int iPgTopic
9830: 3b 0a 20 20 20 20 20 20 20 20 20 20 75 38 20 2a  ;.          u8 *
9840: 70 50 67 4b 65 79 3b 0a 20 20 20 20 20 20 20 20  pPgKey;.        
9850: 20 20 69 6e 74 20 72 65 73 3b 0a 20 20 20 20 20    int res;.     
9860: 20 20 20 20 20 69 6e 74 20 69 43 65 6c 6c 3b 0a       int iCell;.
9870: 0a 20 20 20 20 20 20 20 20 20 20 69 43 65 6c 6c  .          iCell
9880: 20 3d 20 28 28 65 44 69 72 20 3c 20 30 29 20 3f   = ((eDir < 0) ?
9890: 20 28 6e 43 65 6c 6c 2d 31 29 20 3a 20 30 29 3b   (nCell-1) : 0);
98a0: 0a 20 20 20 20 20 20 20 20 20 20 70 50 67 4b 65  .          pPgKe
98b0: 79 20 3d 20 70 61 67 65 47 65 74 4b 65 79 28 70  y = pageGetKey(p
98c0: 53 65 67 2c 20 70 54 65 73 74 2c 20 69 43 65 6c  Seg, pTest, iCel
98d0: 6c 2c 20 26 69 50 67 54 6f 70 69 63 2c 20 26 6e  l, &iPgTopic, &n
98e0: 50 67 4b 65 79 2c 20 26 62 6c 6f 62 29 3b 0a 20  PgKey, &blob);. 
98f0: 20 20 20 20 20 20 20 20 20 72 65 73 20 3d 20 69           res = i
9900: 54 6f 70 69 63 20 2d 20 69 50 67 54 6f 70 69 63  Topic - iPgTopic
9910: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
9920: 72 65 73 3d 3d 30 20 29 20 72 65 73 20 3d 20 70  res==0 ) res = p
9930: 43 73 72 2d 3e 70 44 62 2d 3e 78 43 6d 70 28 70  Csr->pDb->xCmp(p
9940: 4b 65 79 2c 20 6e 4b 65 79 2c 20 70 50 67 4b 65  Key, nKey, pPgKe
9950: 79 2c 20 6e 50 67 4b 65 79 29 3b 0a 20 20 20 20  y, nPgKey);.    
9960: 20 20 20 20 20 20 69 66 28 20 28 65 44 69 72 3d        if( (eDir=
9970: 3d 31 20 26 26 20 72 65 73 3e 30 29 20 7c 7c 20  =1 && res>0) || 
9980: 28 65 44 69 72 3d 3d 2d 31 20 26 26 20 72 65 73  (eDir==-1 && res
9990: 3c 30 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  <0) ){.         
99a0: 20 20 20 2f 2a 20 54 61 6b 69 6e 67 20 74 68 69     /* Taking thi
99b0: 73 20 62 72 61 6e 63 68 20 6d 65 61 6e 73 20 73  s branch means s
99c0: 6f 6d 65 74 68 69 6e 67 20 68 61 73 20 67 6f 6e  omething has gon
99d0: 65 20 77 72 6f 6e 67 2e 20 2a 2f 0a 20 20 20 20  e wrong. */.    
99e0: 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4d          char *zM
99f0: 73 67 20 3d 20 6c 73 6d 4d 61 6c 6c 6f 63 50 72  sg = lsmMallocPr
9a00: 69 6e 74 66 28 70 45 6e 76 2c 20 22 4b 65 79 20  intf(pEnv, "Key 
9a10: 5c 22 25 73 5c 22 20 69 73 20 6e 6f 74 20 6f 6e  \"%s\" is not on
9a20: 20 70 61 67 65 20 25 64 22 2c 20 0a 20 20 20 20   page %d", .    
9a30: 20 20 20 20 20 20 20 20 20 20 20 20 6b 65 79 54              keyT
9a40: 6f 53 74 72 69 6e 67 28 70 45 6e 76 2c 20 70 4b  oString(pEnv, pK
9a50: 65 79 2c 20 6e 4b 65 79 29 2c 20 6c 73 6d 46 73  ey, nKey), lsmFs
9a60: 50 61 67 65 4e 75 6d 62 65 72 28 70 50 74 72 2d  PageNumber(pPtr-
9a70: 3e 70 50 67 29 0a 20 20 20 20 20 20 20 20 20 20  >pPg).          
9a80: 20 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20    );.           
9a90: 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c   fprintf(stderr,
9aa0: 20 22 25 73 5c 6e 22 2c 20 7a 4d 73 67 29 3b 0a   "%s\n", zMsg);.
9ab0: 20 20 20 20 20 20 20 20 20 20 20 20 61 73 73 65              asse
9ac0: 72 74 28 20 21 22 61 73 73 65 72 74 4b 65 79 4c  rt( !"assertKeyL
9ad0: 6f 63 61 74 69 6f 6e 28 29 20 66 61 69 6c 65 64  ocation() failed
9ae0: 22 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  " );.          }
9af0: 0a 20 20 20 20 20 20 20 20 20 20 6c 73 6d 46 73  .          lsmFs
9b00: 50 61 67 65 52 65 6c 65 61 73 65 28 70 54 65 73  PageRelease(pTes
9b10: 74 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70 54  t);.          pT
9b20: 65 73 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  est = 0;.       
9b30: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d   }.      }.    }
9b40: 0a 20 20 7d 0a 0a 20 20 73 6f 72 74 65 64 42 6c  .  }..  sortedBl
9b50: 6f 62 46 72 65 65 28 26 62 6c 6f 62 29 3b 0a 20  obFree(&blob);. 
9b60: 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 23 65 6e   return 1;.}.#en
9b70: 64 69 66 0a 0a 23 69 66 6e 64 65 66 20 4e 44 45  dif..#ifndef NDE
9b80: 42 55 47 0a 73 74 61 74 69 63 20 69 6e 74 20 61  BUG.static int a
9b90: 73 73 65 72 74 53 65 65 6b 52 65 73 75 6c 74 28  ssertSeekResult(
9ba0: 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a  .  MultiCursor *
9bb0: 70 43 73 72 2c 0a 20 20 53 65 67 6d 65 6e 74 50  pCsr,.  SegmentP
9bc0: 74 72 20 2a 70 50 74 72 2c 0a 20 20 69 6e 74 20  tr *pPtr,.  int 
9bd0: 69 54 6f 70 69 63 2c 0a 20 20 76 6f 69 64 20 2a  iTopic,.  void *
9be0: 70 4b 65 79 2c 0a 20 20 69 6e 74 20 6e 4b 65 79  pKey,.  int nKey
9bf0: 2c 0a 20 20 69 6e 74 20 65 53 65 65 6b 0a 29 7b  ,.  int eSeek.){
9c00: 0a 20 20 69 66 28 20 70 50 74 72 2d 3e 70 50 67  .  if( pPtr->pPg
9c10: 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 65 73 3b   ){.    int res;
9c20: 0a 20 20 20 20 72 65 73 20 3d 20 73 6f 72 74 65  .    res = sorte
9c30: 64 4b 65 79 43 6f 6d 70 61 72 65 28 70 43 73 72  dKeyCompare(pCsr
9c40: 2d 3e 70 44 62 2d 3e 78 43 6d 70 2c 20 69 54 6f  ->pDb->xCmp, iTo
9c50: 70 69 63 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 2c  pic, pKey, nKey,
9c60: 0a 20 20 20 20 20 20 20 20 72 74 54 6f 70 69 63  .        rtTopic
9c70: 28 70 50 74 72 2d 3e 65 54 79 70 65 29 2c 20 70  (pPtr->eType), p
9c80: 50 74 72 2d 3e 70 4b 65 79 2c 20 70 50 74 72 2d  Ptr->pKey, pPtr-
9c90: 3e 6e 4b 65 79 0a 20 20 20 20 29 3b 0a 0a 20 20  >nKey.    );..  
9ca0: 20 20 69 66 28 20 65 53 65 65 6b 3d 3d 4c 53 4d    if( eSeek==LSM
9cb0: 5f 53 45 45 4b 5f 45 51 20 29 20 72 65 74 75 72  _SEEK_EQ ) retur
9cc0: 6e 20 28 72 65 73 3d 3d 30 29 3b 0a 20 20 20 20  n (res==0);.    
9cd0: 69 66 28 20 65 53 65 65 6b 3d 3d 4c 53 4d 5f 53  if( eSeek==LSM_S
9ce0: 45 45 4b 5f 4c 45 20 29 20 72 65 74 75 72 6e 20  EEK_LE ) return 
9cf0: 28 72 65 73 3e 3d 30 29 3b 0a 20 20 20 20 69 66  (res>=0);.    if
9d00: 28 20 65 53 65 65 6b 3d 3d 4c 53 4d 5f 53 45 45  ( eSeek==LSM_SEE
9d10: 4b 5f 47 45 20 29 20 72 65 74 75 72 6e 20 28 72  K_GE ) return (r
9d20: 65 73 3c 3d 30 29 3b 0a 20 20 7d 0a 0a 20 20 72  es<=0);.  }..  r
9d30: 65 74 75 72 6e 20 31 3b 0a 7d 0a 23 65 6e 64 69  eturn 1;.}.#endi
9d40: 66 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  f..static int se
9d50: 67 6d 65 6e 74 50 74 72 53 65 61 72 63 68 4f 76  gmentPtrSearchOv
9d60: 65 72 73 69 7a 65 64 28 0a 20 20 4d 75 6c 74 69  ersized(.  Multi
9d70: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20  Cursor *pCsr,   
9d80: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
9d90: 72 73 6f 72 20 63 6f 6e 74 65 78 74 20 2a 2f 0a  rsor context */.
9da0: 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50    SegmentPtr *pP
9db0: 74 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  tr,             
9dc0: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
9dd0: 73 65 65 6b 20 2a 2f 0a 20 20 69 6e 74 20 69 54  seek */.  int iT
9de0: 6f 70 69 63 2c 20 20 20 20 20 20 20 20 20 20 20  opic,           
9df0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 70            /* Top
9e00: 69 63 20 6f 66 20 6b 65 79 20 74 6f 20 73 65 61  ic of key to sea
9e10: 72 63 68 20 66 6f 72 20 2a 2f 0a 20 20 76 6f 69  rch for */.  voi
9e20: 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b 65  d *pKey, int nKe
9e30: 79 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  y            /* 
9e40: 4b 65 79 20 74 6f 20 73 65 65 6b 20 74 6f 20 2a  Key to seek to *
9e50: 2f 0a 29 7b 0a 20 20 69 6e 74 20 28 2a 78 43 6d  /.){.  int (*xCm
9e60: 70 29 28 76 6f 69 64 20 2a 2c 20 69 6e 74 2c 20  p)(void *, int, 
9e70: 76 6f 69 64 20 2a 2c 20 69 6e 74 29 20 3d 20 70  void *, int) = p
9e80: 43 73 72 2d 3e 70 44 62 2d 3e 78 43 6d 70 3b 0a  Csr->pDb->xCmp;.
9e90: 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f    int rc = LSM_O
9ea0: 4b 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20  K;..  /* If the 
9eb0: 4f 56 45 52 53 49 5a 45 44 20 66 6c 61 67 20 69  OVERSIZED flag i
9ec0: 73 20 73 65 74 2c 20 74 68 65 6e 20 74 68 65 72  s set, then ther
9ed0: 65 20 69 73 20 6e 6f 20 70 6f 69 6e 74 65 72 20  e is no pointer 
9ee0: 69 6e 20 74 68 65 0a 20 20 2a 2a 20 75 70 70 65  in the.  ** uppe
9ef0: 72 20 6c 65 76 65 6c 20 74 6f 20 74 68 65 20 6e  r level to the n
9f00: 65 78 74 20 70 61 67 65 20 69 6e 20 74 68 65 20  ext page in the 
9f10: 73 65 67 6d 65 6e 74 20 74 68 61 74 20 63 6f 6e  segment that con
9f20: 74 61 69 6e 73 20 61 74 20 6c 65 61 73 74 0a 20  tains at least. 
9f30: 20 2a 2a 20 6f 6e 65 20 6b 65 79 2e 20 53 6f 20   ** one key. So 
9f40: 63 6f 6d 70 61 72 65 20 74 68 65 20 6c 61 72 67  compare the larg
9f50: 65 73 74 20 6b 65 79 20 6f 6e 20 74 68 65 20 63  est key on the c
9f60: 75 72 72 65 6e 74 20 70 61 67 65 20 77 69 74 68  urrent page with
9f70: 20 74 68 65 0a 20 20 2a 2a 20 6b 65 79 20 62 65   the.  ** key be
9f80: 69 6e 67 20 73 6f 75 67 68 74 20 28 70 4b 65 79  ing sought (pKey
9f90: 2f 6e 4b 65 79 29 2e 20 49 66 20 28 70 4b 65 79  /nKey). If (pKey
9fa0: 2f 6e 4b 65 79 29 20 69 73 20 6c 61 72 67 65 72  /nKey) is larger
9fb0: 2c 20 61 64 76 61 6e 63 65 0a 20 20 2a 2a 20 74  , advance.  ** t
9fc0: 6f 20 74 68 65 20 6e 65 78 74 20 70 61 67 65 20  o the next page 
9fd0: 69 6e 20 74 68 65 20 73 65 67 6d 65 6e 74 20 74  in the segment t
9fe0: 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 61 74 20  hat contains at 
9ff0: 6c 65 61 73 74 20 6f 6e 65 20 6b 65 79 2e 20 0a  least one key. .
a000: 20 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 72 63    */.  while( rc
a010: 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 28 70 50 74  ==LSM_OK && (pPt
a020: 72 2d 3e 66 6c 61 67 73 20 26 20 50 47 46 54 52  r->flags & PGFTR
a030: 5f 53 4b 49 50 5f 4e 45 58 54 5f 46 4c 41 47 29  _SKIP_NEXT_FLAG)
a040: 20 29 7b 0a 20 20 20 20 75 38 20 2a 70 4c 61 73   ){.    u8 *pLas
a050: 74 4b 65 79 3b 0a 20 20 20 20 69 6e 74 20 6e 4c  tKey;.    int nL
a060: 61 73 74 4b 65 79 3b 0a 20 20 20 20 69 6e 74 20  astKey;.    int 
a070: 69 4c 61 73 74 54 6f 70 69 63 3b 0a 20 20 20 20  iLastTopic;.    
a080: 69 6e 74 20 72 65 73 3b 20 20 20 20 20 20 20 20  int res;        
a090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
a0a0: 20 52 65 73 75 6c 74 20 6f 66 20 63 6f 6d 70 61   Result of compa
a0b0: 72 69 73 6f 6e 20 2a 2f 0a 20 20 20 20 50 61 67  rison */.    Pag
a0c0: 65 20 2a 70 4e 65 78 74 3b 0a 0a 20 20 20 20 2f  e *pNext;..    /
a0d0: 2a 20 4c 6f 61 64 20 74 68 65 20 6c 61 73 74 20  * Load the last 
a0e0: 6b 65 79 20 6f 6e 20 74 68 65 20 63 75 72 72 65  key on the curre
a0f0: 6e 74 20 70 61 67 65 2e 20 2a 2f 0a 20 20 20 20  nt page. */.    
a100: 70 4c 61 73 74 4b 65 79 20 3d 20 70 61 67 65 47  pLastKey = pageG
a110: 65 74 4b 65 79 28 70 50 74 72 2d 3e 70 53 65 67  etKey(pPtr->pSeg
a120: 2c 0a 20 20 20 20 20 20 20 20 70 50 74 72 2d 3e  ,.        pPtr->
a130: 70 50 67 2c 20 70 50 74 72 2d 3e 6e 43 65 6c 6c  pPg, pPtr->nCell
a140: 2d 31 2c 20 26 69 4c 61 73 74 54 6f 70 69 63 2c  -1, &iLastTopic,
a150: 20 26 6e 4c 61 73 74 4b 65 79 2c 20 26 70 50 74   &nLastKey, &pPt
a160: 72 2d 3e 62 6c 6f 62 31 0a 20 20 20 20 29 3b 0a  r->blob1.    );.
a170: 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 6c  .    /* If the l
a180: 6f 61 64 65 64 20 6b 65 79 20 69 73 20 3e 3d 20  oaded key is >= 
a190: 74 68 61 6e 20 28 70 4b 65 79 2f 6e 4b 65 79 29  than (pKey/nKey)
a1a0: 2c 20 62 72 65 61 6b 20 6f 75 74 20 6f 66 20 74  , break out of t
a1b0: 68 65 20 6c 6f 6f 70 2e 0a 20 20 20 20 2a 2a 20  he loop..    ** 
a1c0: 49 66 20 28 70 4b 65 79 2f 6e 4b 65 79 29 20 69  If (pKey/nKey) i
a1d0: 73 20 70 72 65 73 65 6e 74 20 69 6e 20 74 68 69  s present in thi
a1e0: 73 20 61 72 72 61 79 2c 20 69 74 20 6d 75 73 74  s array, it must
a1f0: 20 62 65 20 6f 6e 20 74 68 65 20 63 75 72 72 65   be on the curre
a200: 6e 74 20 0a 20 20 20 20 2a 2a 20 70 61 67 65 2e  nt .    ** page.
a210: 20 20 2a 2f 0a 20 20 20 20 72 65 73 20 3d 20 73    */.    res = s
a220: 6f 72 74 65 64 4b 65 79 43 6f 6d 70 61 72 65 28  ortedKeyCompare(
a230: 0a 20 20 20 20 20 20 20 20 78 43 6d 70 2c 20 69  .        xCmp, i
a240: 4c 61 73 74 54 6f 70 69 63 2c 20 70 4c 61 73 74  LastTopic, pLast
a250: 4b 65 79 2c 20 6e 4c 61 73 74 4b 65 79 2c 20 69  Key, nLastKey, i
a260: 54 6f 70 69 63 2c 20 70 4b 65 79 2c 20 6e 4b 65  Topic, pKey, nKe
a270: 79 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28  y.    );.    if(
a280: 20 72 65 73 3e 3d 30 20 29 20 62 72 65 61 6b 3b   res>=0 ) break;
a290: 0a 0a 20 20 20 20 2f 2a 20 41 64 76 61 6e 63 65  ..    /* Advance
a2a0: 20 74 6f 20 74 68 65 20 6e 65 78 74 20 70 61 67   to the next pag
a2b0: 65 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20  e that contains 
a2c0: 61 74 20 6c 65 61 73 74 20 6f 6e 65 20 6b 65 79  at least one key
a2d0: 2e 20 2a 2f 0a 20 20 20 20 70 4e 65 78 74 20 3d  . */.    pNext =
a2e0: 20 70 50 74 72 2d 3e 70 50 67 3b 0a 20 20 20 20   pPtr->pPg;.    
a2f0: 6c 73 6d 46 73 50 61 67 65 52 65 66 28 70 4e 65  lsmFsPageRef(pNe
a300: 78 74 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  xt);.    while( 
a310: 31 20 29 7b 0a 20 20 20 20 20 20 50 61 67 65 20  1 ){.      Page 
a320: 2a 70 4c 6f 61 64 3b 0a 20 20 20 20 20 20 75 38  *pLoad;.      u8
a330: 20 2a 61 44 61 74 61 3b 20 69 6e 74 20 6e 44 61   *aData; int nDa
a340: 74 61 3b 0a 0a 20 20 20 20 20 20 72 63 20 3d 20  ta;..      rc = 
a350: 6c 73 6d 46 73 44 62 50 61 67 65 4e 65 78 74 28  lsmFsDbPageNext(
a360: 70 50 74 72 2d 3e 70 53 65 67 2c 20 70 4e 65 78  pPtr->pSeg, pNex
a370: 74 2c 20 31 2c 20 26 70 4c 6f 61 64 29 3b 0a 20  t, 1, &pLoad);. 
a380: 20 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65       lsmFsPageRe
a390: 6c 65 61 73 65 28 70 4e 65 78 74 29 3b 0a 20 20  lease(pNext);.  
a3a0: 20 20 20 20 70 4e 65 78 74 20 3d 20 70 4c 6f 61      pNext = pLoa
a3b0: 64 3b 0a 20 20 20 20 20 20 69 66 28 20 70 4e 65  d;.      if( pNe
a3c0: 78 74 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 0a  xt==0 ) break;..
a3d0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63        assert( rc
a3e0: 3d 3d 4c 53 4d 5f 4f 4b 20 29 3b 0a 20 20 20 20  ==LSM_OK );.    
a3f0: 20 20 61 44 61 74 61 20 3d 20 6c 73 6d 46 73 50    aData = lsmFsP
a400: 61 67 65 44 61 74 61 28 70 4e 65 78 74 2c 20 26  ageData(pNext, &
a410: 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20 69 66  nData);.      if
a420: 28 20 28 70 61 67 65 47 65 74 46 6c 61 67 73 28  ( (pageGetFlags(
a430: 61 44 61 74 61 2c 20 6e 44 61 74 61 29 20 26 20  aData, nData) & 
a440: 53 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c  SEGMENT_BTREE_FL
a450: 41 47 29 3d 3d 30 0a 20 20 20 20 20 20 20 26 26  AG)==0.       &&
a460: 20 70 61 67 65 47 65 74 4e 52 65 63 28 61 44 61   pageGetNRec(aDa
a470: 74 61 2c 20 6e 44 61 74 61 29 3e 30 0a 20 20 20  ta, nData)>0.   
a480: 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 62 72     ){.        br
a490: 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
a4a0: 20 7d 0a 20 20 20 20 69 66 28 20 70 4e 65 78 74   }.    if( pNext
a4b0: 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  ==0 ) break;.   
a4c0: 20 73 65 67 6d 65 6e 74 50 74 72 53 65 74 50 61   segmentPtrSetPa
a4d0: 67 65 28 70 50 74 72 2c 20 70 4e 65 78 74 29 3b  ge(pPtr, pNext);
a4e0: 0a 0a 20 20 20 20 2f 2a 20 54 68 69 73 20 73 68  ..    /* This sh
a4f0: 6f 75 6c 64 20 70 72 6f 62 61 62 6c 79 20 62 65  ould probably be
a500: 20 61 6e 20 4c 53 4d 5f 43 4f 52 52 55 50 54 20   an LSM_CORRUPT 
a510: 65 72 72 6f 72 2e 20 2a 2f 0a 20 20 20 20 61 73  error. */.    as
a520: 73 65 72 74 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b  sert( rc!=LSM_OK
a530: 20 7c 7c 20 28 70 50 74 72 2d 3e 66 6c 61 67 73   || (pPtr->flags
a540: 20 26 20 50 47 46 54 52 5f 53 4b 49 50 5f 54 48   & PGFTR_SKIP_TH
a550: 49 53 5f 46 4c 41 47 29 20 29 3b 0a 20 20 7d 0a  IS_FLAG) );.  }.
a560: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
a570: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 74 72 46  .static int ptrF
a580: 77 64 50 6f 69 6e 74 65 72 28 0a 20 20 50 61 67  wdPointer(.  Pag
a590: 65 20 2a 70 50 61 67 65 2c 0a 20 20 69 6e 74 20  e *pPage,.  int 
a5a0: 69 43 65 6c 6c 2c 0a 20 20 53 65 67 6d 65 6e 74  iCell,.  Segment
a5b0: 20 2a 70 53 65 67 2c 0a 20 20 50 67 6e 6f 20 2a   *pSeg,.  Pgno *
a5c0: 70 69 50 74 72 2c 0a 20 20 69 6e 74 20 2a 70 62  piPtr,.  int *pb
a5d0: 46 6f 75 6e 64 0a 29 7b 0a 20 20 50 61 67 65 20  Found.){.  Page 
a5e0: 2a 70 50 67 20 3d 20 70 50 61 67 65 3b 0a 20 20  *pPg = pPage;.  
a5f0: 69 6e 74 20 69 46 69 72 73 74 20 3d 20 69 43 65  int iFirst = iCe
a600: 6c 6c 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c  ll;.  int rc = L
a610: 53 4d 5f 4f 4b 3b 0a 0a 20 20 64 6f 20 7b 0a 20  SM_OK;..  do {. 
a620: 20 20 20 50 61 67 65 20 2a 70 4e 65 78 74 20 3d     Page *pNext =
a630: 20 30 3b 0a 20 20 20 20 75 38 20 2a 61 44 61 74   0;.    u8 *aDat
a640: 61 3b 0a 20 20 20 20 69 6e 74 20 6e 44 61 74 61  a;.    int nData
a650: 3b 0a 0a 20 20 20 20 61 44 61 74 61 20 3d 20 6c  ;..    aData = l
a660: 73 6d 46 73 50 61 67 65 44 61 74 61 28 70 50 67  smFsPageData(pPg
a670: 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 69  , &nData);.    i
a680: 66 28 20 28 70 61 67 65 47 65 74 46 6c 61 67 73  f( (pageGetFlags
a690: 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29 20 26  (aData, nData) &
a6a0: 20 53 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46   SEGMENT_BTREE_F
a6b0: 4c 41 47 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  LAG)==0 ){.     
a6c0: 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 69 6e   int i;.      in
a6d0: 74 20 6e 43 65 6c 6c 20 3d 20 70 61 67 65 47 65  t nCell = pageGe
a6e0: 74 4e 52 65 63 28 61 44 61 74 61 2c 20 6e 44 61  tNRec(aData, nDa
a6f0: 74 61 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69  ta);.      for(i
a700: 3d 69 46 69 72 73 74 3b 20 69 3c 6e 43 65 6c 6c  =iFirst; i<nCell
a710: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
a720: 75 38 20 65 54 79 70 65 20 3d 20 2a 70 61 67 65  u8 eType = *page
a730: 47 65 74 43 65 6c 6c 28 61 44 61 74 61 2c 20 6e  GetCell(aData, n
a740: 44 61 74 61 2c 20 69 29 3b 0a 20 20 20 20 20 20  Data, i);.      
a750: 20 20 69 66 28 20 28 65 54 79 70 65 20 26 20 4c    if( (eType & L
a760: 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45 54 45 29  SM_START_DELETE)
a770: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
a780: 20 2a 70 62 46 6f 75 6e 64 20 3d 20 31 3b 0a 20   *pbFound = 1;. 
a790: 20 20 20 20 20 20 20 20 20 2a 70 69 50 74 72 20           *piPtr 
a7a0: 3d 20 70 61 67 65 47 65 74 52 65 63 6f 72 64 50  = pageGetRecordP
a7b0: 74 72 28 61 44 61 74 61 2c 20 6e 44 61 74 61 2c  tr(aData, nData,
a7c0: 20 69 29 20 2b 20 70 61 67 65 47 65 74 50 74 72   i) + pageGetPtr
a7d0: 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a  (aData, nData);.
a7e0: 20 20 20 20 20 20 20 20 20 20 6c 73 6d 46 73 50            lsmFsP
a7f0: 61 67 65 52 65 6c 65 61 73 65 28 70 50 67 29 3b  ageRelease(pPg);
a800: 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72  .          retur
a810: 6e 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 20 20 20 20  n LSM_OK;.      
a820: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
a830: 7d 0a 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 46  }..    rc = lsmF
a840: 73 44 62 50 61 67 65 4e 65 78 74 28 70 53 65 67  sDbPageNext(pSeg
a850: 2c 20 70 50 67 2c 20 31 2c 20 26 70 4e 65 78 74  , pPg, 1, &pNext
a860: 29 3b 0a 20 20 20 20 6c 73 6d 46 73 50 61 67 65  );.    lsmFsPage
a870: 52 65 6c 65 61 73 65 28 70 50 67 29 3b 0a 20 20  Release(pPg);.  
a880: 20 20 70 50 67 20 3d 20 70 4e 65 78 74 3b 0a 20    pPg = pNext;. 
a890: 20 20 20 69 46 69 72 73 74 20 3d 20 30 3b 0a 20     iFirst = 0;. 
a8a0: 20 7d 77 68 69 6c 65 28 20 70 50 67 20 26 26 20   }while( pPg && 
a8b0: 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 3b 0a 20 20  rc==LSM_OK );.  
a8c0: 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61 73 65  lsmFsPageRelease
a8d0: 28 70 50 67 29 3b 0a 0a 20 20 2a 70 62 46 6f 75  (pPg);..  *pbFou
a8e0: 6e 64 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e  nd = 0;.  return
a8f0: 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69   rc;.}..static i
a900: 6e 74 20 73 6f 72 74 65 64 52 68 73 46 69 72 73  nt sortedRhsFirs
a910: 74 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70  t(MultiCursor *p
a920: 43 73 72 2c 20 4c 65 76 65 6c 20 2a 70 4c 76 6c  Csr, Level *pLvl
a930: 2c 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50  , SegmentPtr *pP
a940: 74 72 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  tr){.  int rc;. 
a950: 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74 72   rc = segmentPtr
a960: 45 6e 64 28 70 43 73 72 2c 20 70 50 74 72 2c 20  End(pCsr, pPtr, 
a970: 30 29 3b 0a 20 20 77 68 69 6c 65 28 20 70 50 74  0);.  while( pPt
a980: 72 2d 3e 70 50 67 20 26 26 20 72 63 3d 3d 4c 53  r->pPg && rc==LS
a990: 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20  M_OK ){.    int 
a9a0: 72 65 73 20 3d 20 73 6f 72 74 65 64 4b 65 79 43  res = sortedKeyC
a9b0: 6f 6d 70 61 72 65 28 70 43 73 72 2d 3e 70 44 62  ompare(pCsr->pDb
a9c0: 2d 3e 78 43 6d 70 2c 0a 20 20 20 20 20 20 20 20  ->xCmp,.        
a9d0: 70 4c 76 6c 2d 3e 69 53 70 6c 69 74 54 6f 70 69  pLvl->iSplitTopi
a9e0: 63 2c 20 70 4c 76 6c 2d 3e 70 53 70 6c 69 74 4b  c, pLvl->pSplitK
a9f0: 65 79 2c 20 70 4c 76 6c 2d 3e 6e 53 70 6c 69 74  ey, pLvl->nSplit
aa00: 4b 65 79 2c 0a 20 20 20 20 20 20 20 20 72 74 54  Key,.        rtT
aa10: 6f 70 69 63 28 70 50 74 72 2d 3e 65 54 79 70 65  opic(pPtr->eType
aa20: 29 2c 20 70 50 74 72 2d 3e 70 4b 65 79 2c 20 70  ), pPtr->pKey, p
aa30: 50 74 72 2d 3e 6e 4b 65 79 0a 20 20 20 20 29 3b  Ptr->nKey.    );
aa40: 0a 20 20 20 20 69 66 28 20 72 65 73 3c 3d 30 20  .    if( res<=0 
aa50: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 72 63 20  ) break;.    rc 
aa60: 3d 20 73 65 67 6d 65 6e 74 50 74 72 41 64 76 61  = segmentPtrAdva
aa70: 6e 63 65 28 70 43 73 72 2c 20 70 50 74 72 2c 20  nce(pCsr, pPtr, 
aa80: 30 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  0);.  }.  return
aa90: 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 54   rc;.}.../*.** T
aaa0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
aab0: 63 61 6c 6c 65 64 20 61 73 20 70 61 72 74 20 6f  called as part o
aac0: 66 20 61 20 53 45 45 4b 5f 47 45 20 6f 70 20 6f  f a SEEK_GE op o
aad0: 6e 20 61 20 6d 75 6c 74 69 2d 63 75 72 73 6f 72  n a multi-cursor
aae0: 20 69 66 20 74 68 65 20 0a 2a 2a 20 46 43 20 70   if the .** FC p
aaf0: 6f 69 6e 74 65 72 20 72 65 61 64 20 66 72 6f 6d  ointer read from
ab00: 20 73 65 67 6d 65 6e 74 20 2a 70 50 74 72 20 63   segment *pPtr c
ab10: 6f 6d 65 73 20 66 72 6f 6d 20 61 6e 20 65 6e 74  omes from an ent
ab20: 72 79 20 77 69 74 68 20 74 68 65 20 0a 2a 2a 20  ry with the .** 
ab30: 4c 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45 54 45  LSM_START_DELETE
ab40: 20 66 6c 61 67 20 73 65 74 2e 20 49 6e 20 74 68   flag set. In th
ab50: 69 73 20 63 61 73 65 20 74 68 65 20 70 6f 69 6e  is case the poin
ab60: 74 65 72 20 76 61 6c 75 65 20 63 61 6e 6e 6f 74  ter value cannot
ab70: 20 62 65 20 0a 2a 2a 20 74 72 75 73 74 65 64 2e   be .** trusted.
ab80: 20 49 6e 73 74 65 61 64 2c 20 74 68 65 20 70 6f   Instead, the po
ab90: 69 6e 74 65 72 20 74 68 61 74 20 73 68 6f 75 6c  inter that shoul
aba0: 64 20 62 65 20 66 6f 6c 6c 6f 77 65 64 20 69 73  d be followed is
abb0: 20 74 68 61 74 20 61 73 73 6f 63 69 61 74 65 64   that associated
abc0: 0a 2a 2a 20 77 69 74 68 20 74 68 65 20 6e 65 78  .** with the nex
abd0: 74 20 65 6e 74 72 79 20 69 6e 20 2a 70 50 74 72  t entry in *pPtr
abe0: 20 74 68 61 74 20 64 6f 65 73 20 6e 6f 74 20 68   that does not h
abf0: 61 76 65 20 4c 53 4d 5f 53 54 41 52 54 5f 44 45  ave LSM_START_DE
ac00: 4c 45 54 45 20 73 65 74 2e 0a 2a 2a 0a 2a 2a 20  LETE set..**.** 
ac10: 57 68 79 20 74 68 65 20 70 6f 69 6e 74 65 72 73  Why the pointers
ac20: 20 63 61 6e 27 74 20 62 65 20 74 72 75 73 74 65   can't be truste
ac30: 64 3a 0a 2a 2a 0a 2a 2a 0a 2a 2a 0a 2a 2a 20 54  d:.**.**.**.** T
ac40: 4f 44 4f 3a 20 54 68 69 73 20 69 73 20 61 20 73  ODO: This is a s
ac50: 74 6f 70 2d 67 61 70 20 73 6f 6c 75 74 69 6f 6e  top-gap solution
ac60: 3a 0a 2a 2a 20 0a 2a 2a 20 20 20 41 74 20 74 68  :.** .**   At th
ac70: 65 20 6d 6f 6d 65 6e 74 2c 20 74 68 69 73 20 66  e moment, this f
ac80: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
ac90: 64 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 73 65  d from within se
aca0: 67 6d 65 6e 74 50 74 72 53 65 65 6b 28 29 2c 20  gmentPtrSeek(), 
acb0: 0a 2a 2a 20 20 20 61 73 20 70 61 72 74 20 6f 66  .**   as part of
acc0: 20 74 68 65 20 69 6e 69 74 69 61 6c 20 6c 73 6d   the initial lsm
acd0: 4d 43 75 72 73 6f 72 53 65 65 6b 28 29 20 63 61  MCursorSeek() ca
ace0: 6c 6c 2e 20 48 6f 77 65 76 65 72 2c 20 63 6f 6e  ll. However, con
acf0: 73 69 64 65 72 20 61 20 0a 2a 2a 20 20 20 64 61  sider a .**   da
ad00: 74 61 62 61 73 65 20 77 68 65 72 65 20 74 68 65  tabase where the
ad10: 20 66 6f 6c 6c 6f 77 69 6e 67 20 68 61 73 20 6f   following has o
ad20: 63 63 75 72 72 65 64 3a 0a 2a 2a 0a 2a 2a 20 20  ccurred:.**.**  
ad30: 20 20 20 20 31 2e 20 41 20 72 61 6e 67 65 20 64      1. A range d
ad40: 65 6c 65 74 65 20 72 65 6d 6f 76 65 73 20 6b 65  elete removes ke
ad50: 79 73 20 31 2e 2e 39 39 39 39 20 75 73 69 6e 67  ys 1..9999 using
ad60: 20 61 20 72 61 6e 67 65 20 64 65 6c 65 74 65 2e   a range delete.
ad70: 0a 2a 2a 20 20 20 20 20 20 32 2e 20 4b 65 79 73  .**      2. Keys
ad80: 20 31 20 74 68 72 6f 75 67 68 20 39 39 39 39 20   1 through 9999 
ad90: 61 72 65 20 72 65 69 6e 73 65 72 74 65 64 2e 0a  are reinserted..
ada0: 2a 2a 20 20 20 20 20 20 33 2e 20 54 68 65 20 6c  **      3. The l
adb0: 65 76 65 6c 73 20 63 6f 6e 74 61 69 6e 69 6e 67  evels containing
adc0: 20 74 68 65 20 6f 70 73 20 69 6e 20 31 2e 20 61   the ops in 1. a
add0: 6e 64 20 32 2e 20 61 62 6f 76 65 20 61 72 65 20  nd 2. above are 
ade0: 6d 65 72 67 65 64 2e 20 43 61 6c 6c 0a 2a 2a 20  merged. Call.** 
adf0: 20 20 20 20 20 20 20 20 74 68 69 73 20 6c 65 76          this lev
ae00: 65 6c 20 4e 2e 20 4c 65 76 65 6c 20 4e 20 63 6f  el N. Level N co
ae10: 6e 74 61 69 6e 73 20 46 43 20 70 6f 69 6e 74 65  ntains FC pointe
ae20: 72 73 20 74 6f 20 6c 65 76 65 6c 20 4e 2b 31 2e  rs to level N+1.
ae30: 0a 2a 2a 0a 2a 2a 20 20 20 54 68 65 6e 2c 20 69  .**.**   Then, i
ae40: 66 20 74 68 65 20 75 73 65 72 20 61 74 74 65 6d  f the user attem
ae50: 70 74 73 20 74 6f 20 71 75 65 72 79 20 66 6f 72  pts to query for
ae60: 20 28 6b 65 79 3e 3d 32 20 4c 49 4d 49 54 20 31   (key>=2 LIMIT 1
ae70: 30 29 2c 20 74 68 65 20 0a 2a 2a 20 20 20 6c 73  0), the .**   ls
ae80: 6d 4d 43 75 72 73 6f 72 53 65 65 6b 28 29 20 63  mMCursorSeek() c
ae90: 61 6c 6c 20 77 69 6c 6c 20 69 74 65 72 61 74 65  all will iterate
aea0: 20 74 68 72 6f 75 67 68 20 39 39 39 38 20 65 6e   through 9998 en
aeb0: 74 72 69 65 73 20 73 65 61 72 63 68 69 6e 67 20  tries searching 
aec0: 66 6f 72 20 61 20 0a 2a 2a 20 20 20 70 6f 69 6e  for a .**   poin
aed0: 74 65 72 20 64 6f 77 6e 20 74 6f 20 74 68 65 20  ter down to the 
aee0: 6c 65 76 65 6c 20 4e 2b 31 20 74 68 61 74 20 69  level N+1 that i
aef0: 73 20 6e 65 76 65 72 20 61 63 74 75 61 6c 6c 79  s never actually
af00: 20 75 73 65 64 2e 20 49 74 20 77 6f 75 6c 64 20   used. It would 
af10: 62 65 0a 2a 2a 20 20 20 6d 75 63 68 20 62 65 74  be.**   much bet
af20: 74 65 72 20 69 66 20 74 68 65 20 6d 75 6c 74 69  ter if the multi
af30: 2d 63 75 72 73 6f 72 20 63 6f 75 6c 64 20 64 6f  -cursor could do
af40: 20 74 68 69 73 20 6c 61 7a 69 6c 79 20 2d 20 6f   this lazily - o
af50: 6e 6c 79 20 73 65 65 6b 20 74 6f 20 74 68 65 0a  nly seek to the.
af60: 2a 2a 20 20 20 6c 65 76 65 6c 20 28 4e 2b 31 29  **   level (N+1)
af70: 20 70 61 67 65 20 61 66 74 65 72 20 74 68 65 20   page after the 
af80: 75 73 65 72 20 68 61 73 20 6d 6f 76 65 64 20 74  user has moved t
af90: 68 65 20 63 75 72 73 6f 72 20 6f 6e 20 6c 65 76  he cursor on lev
afa0: 65 6c 20 4e 20 70 61 73 73 65 64 0a 2a 2a 20 20  el N passed.**  
afb0: 20 74 68 65 20 62 69 67 20 72 61 6e 67 65 2d 64   the big range-d
afc0: 65 6c 65 74 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  elete..*/.static
afd0: 20 69 6e 74 20 73 65 67 6d 65 6e 74 50 74 72 46   int segmentPtrF
afe0: 77 64 50 6f 69 6e 74 65 72 28 0a 20 20 4d 75 6c  wdPointer(.  Mul
aff0: 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  tiCursor *pCsr, 
b000: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
b010: 4d 75 6c 74 69 2d 63 75 72 73 6f 72 20 70 50 74  Multi-cursor pPt
b020: 72 20 62 65 6c 6f 6e 67 73 20 74 6f 20 2a 2f 0a  r belongs to */.
b030: 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50    SegmentPtr *pP
b040: 74 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  tr,             
b050: 20 20 2f 2a 20 53 65 67 6d 65 6e 74 2d 70 6f 69    /* Segment-poi
b060: 6e 74 65 72 20 74 6f 20 65 78 74 72 61 63 74 20  nter to extract 
b070: 46 43 20 70 74 72 20 66 72 6f 6d 20 2a 2f 0a 20  FC ptr from */. 
b080: 20 50 67 6e 6f 20 2a 70 69 50 74 72 20 20 20 20   Pgno *piPtr    
b090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b0a0: 20 2f 2a 20 4f 55 54 3a 20 46 43 20 70 6f 69 6e   /* OUT: FC poin
b0b0: 74 65 72 20 76 61 6c 75 65 20 2a 2f 0a 29 7b 0a  ter value */.){.
b0c0: 20 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 20 3d 20    Level *pLvl = 
b0d0: 70 50 74 72 2d 3e 70 4c 65 76 65 6c 3b 0a 20 20  pPtr->pLevel;.  
b0e0: 4c 65 76 65 6c 20 2a 70 4e 65 78 74 20 3d 20 70  Level *pNext = p
b0f0: 4c 76 6c 2d 3e 70 4e 65 78 74 3b 0a 20 20 50 61  Lvl->pNext;.  Pa
b100: 67 65 20 2a 70 50 67 20 3d 20 70 50 74 72 2d 3e  ge *pPg = pPtr->
b110: 70 50 67 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  pPg;.  int rc;. 
b120: 20 69 6e 74 20 62 46 6f 75 6e 64 3b 0a 20 20 50   int bFound;.  P
b130: 67 6e 6f 20 69 4f 75 74 20 3d 20 30 3b 0a 0a 20  gno iOut = 0;.. 
b140: 20 69 66 28 20 70 50 74 72 2d 3e 70 53 65 67 3d   if( pPtr->pSeg=
b150: 3d 26 70 4c 76 6c 2d 3e 6c 68 73 20 7c 7c 20 70  =&pLvl->lhs || p
b160: 50 74 72 2d 3e 70 53 65 67 3d 3d 26 70 4c 76 6c  Ptr->pSeg==&pLvl
b170: 2d 3e 61 52 68 73 5b 70 4c 76 6c 2d 3e 6e 52 69  ->aRhs[pLvl->nRi
b180: 67 68 74 2d 31 5d 20 29 7b 0a 20 20 20 20 69 66  ght-1] ){.    if
b190: 28 20 70 4e 65 78 74 3d 3d 30 20 0a 20 20 20 20  ( pNext==0 .    
b1a0: 20 20 20 20 7c 7c 20 28 70 4e 65 78 74 2d 3e 6e      || (pNext->n
b1b0: 52 69 67 68 74 3d 3d 30 20 26 26 20 70 4e 65 78  Right==0 && pNex
b1c0: 74 2d 3e 6c 68 73 2e 69 52 6f 6f 74 29 0a 20 20  t->lhs.iRoot).  
b1d0: 20 20 20 20 20 20 7c 7c 20 28 70 4e 65 78 74 2d        || (pNext-
b1e0: 3e 6e 52 69 67 68 74 21 3d 30 20 26 26 20 70 4e  >nRight!=0 && pN
b1f0: 65 78 74 2d 3e 61 52 68 73 5b 30 5d 2e 69 52 6f  ext->aRhs[0].iRo
b200: 6f 74 29 0a 20 20 20 20 20 20 29 7b 0a 20 20 20  ot).      ){.   
b210: 20 20 20 2f 2a 20 44 6f 20 6e 6f 74 68 69 6e 67     /* Do nothing
b220: 2e 20 54 68 65 20 70 6f 69 6e 74 65 72 20 77 69  . The pointer wi
b230: 6c 6c 20 6e 6f 74 20 62 65 20 75 73 65 64 20 61  ll not be used a
b240: 6e 79 77 61 79 2e 20 2a 2f 0a 20 20 20 20 20 20  nyway. */.      
b250: 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 20  return LSM_OK;. 
b260: 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20     }.  }else{.  
b270: 20 20 69 66 28 20 70 50 74 72 5b 31 5d 2e 70 53    if( pPtr[1].pS
b280: 65 67 2d 3e 69 52 6f 6f 74 20 29 7b 0a 20 20 20  eg->iRoot ){.   
b290: 20 20 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b     return LSM_OK
b2a0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  ;.    }.  }..  /
b2b0: 2a 20 53 65 61 72 63 68 20 66 6f 72 20 61 20 70  * Search for a p
b2c0: 6f 69 6e 74 65 72 20 77 69 74 68 69 6e 20 74 68  ointer within th
b2d0: 65 20 63 75 72 72 65 6e 74 20 73 65 67 6d 65 6e  e current segmen
b2e0: 74 2e 20 2a 2f 0a 20 20 6c 73 6d 46 73 50 61 67  t. */.  lsmFsPag
b2f0: 65 52 65 66 28 70 50 67 29 3b 0a 20 20 72 63 20  eRef(pPg);.  rc 
b300: 3d 20 70 74 72 46 77 64 50 6f 69 6e 74 65 72 28  = ptrFwdPointer(
b310: 70 50 67 2c 20 70 50 74 72 2d 3e 69 43 65 6c 6c  pPg, pPtr->iCell
b320: 2c 20 70 50 74 72 2d 3e 70 53 65 67 2c 20 26 69  , pPtr->pSeg, &i
b330: 4f 75 74 2c 20 26 62 46 6f 75 6e 64 29 3b 0a 0a  Out, &bFound);..
b340: 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
b350: 20 26 26 20 62 46 6f 75 6e 64 3d 3d 30 20 29 7b   && bFound==0 ){
b360: 0a 20 20 20 20 2f 2a 20 54 68 69 73 20 63 61 73  .    /* This cas
b370: 65 20 68 61 70 70 65 6e 73 20 77 68 65 6e 20 70  e happens when p
b380: 50 74 72 20 70 6f 69 6e 74 73 20 74 6f 20 74 68  Ptr points to th
b390: 65 20 6c 65 66 74 2d 68 61 6e 64 2d 73 69 64 65  e left-hand-side
b3a0: 20 6f 66 20 61 20 73 65 67 6d 65 6e 74 0a 20 20   of a segment.  
b3b0: 20 20 2a 2a 20 63 75 72 72 65 6e 74 6c 79 20 75    ** currently u
b3c0: 6e 64 65 72 67 6f 69 6e 67 20 61 6e 20 69 6e 63  ndergoing an inc
b3d0: 72 65 6d 65 6e 74 61 6c 20 6d 65 72 67 65 2e 20  remental merge. 
b3e0: 49 6e 20 74 68 69 73 20 63 61 73 65 2c 20 6a 75  In this case, ju
b3f0: 6d 70 20 74 6f 20 74 68 65 0a 20 20 20 20 2a 2a  mp to the.    **
b400: 20 6f 6c 64 65 73 74 20 73 65 67 6d 65 6e 74 20   oldest segment 
b410: 69 6e 20 74 68 65 20 72 69 67 68 74 2d 68 61 6e  in the right-han
b420: 64 2d 73 69 64 65 20 6f 66 20 74 68 65 20 73 61  d-side of the sa
b430: 6d 65 20 6c 65 76 65 6c 20 61 6e 64 20 63 6f 6e  me level and con
b440: 74 69 6e 75 65 0a 20 20 20 20 2a 2a 20 73 65 61  tinue.    ** sea
b450: 72 63 68 69 6e 67 2e 20 42 75 74 20 2d 20 64 6f  rching. But - do
b460: 20 6e 6f 74 20 63 6f 6e 73 69 64 65 72 20 61 6e   not consider an
b470: 79 20 6b 65 79 73 20 73 6d 61 6c 6c 65 72 20 74  y keys smaller t
b480: 68 61 6e 20 74 68 65 20 6c 65 76 65 6c 73 0a 20  han the levels. 
b490: 20 20 20 2a 2a 20 73 70 6c 69 74 2d 6b 65 79 2e     ** split-key.
b4a0: 20 2a 2f 0a 20 20 20 20 53 65 67 6d 65 6e 74 50   */.    SegmentP
b4b0: 74 72 20 70 74 72 3b 0a 0a 20 20 20 20 69 66 28  tr ptr;..    if(
b4c0: 20 70 50 74 72 2d 3e 70 4c 65 76 65 6c 2d 3e 6e   pPtr->pLevel->n
b4d0: 52 69 67 68 74 3d 3d 30 20 7c 7c 20 70 50 74 72  Right==0 || pPtr
b4e0: 2d 3e 70 53 65 67 21 3d 26 70 50 74 72 2d 3e 70  ->pSeg!=&pPtr->p
b4f0: 4c 65 76 65 6c 2d 3e 6c 68 73 20 29 7b 0a 20 20  Level->lhs ){.  
b500: 20 20 20 20 72 65 74 75 72 6e 20 4c 53 4d 5f 43      return LSM_C
b510: 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20  ORRUPT_BKPT;.   
b520: 20 7d 0a 0a 20 20 20 20 6d 65 6d 73 65 74 28 26   }..    memset(&
b530: 70 74 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53  ptr, 0, sizeof(S
b540: 65 67 6d 65 6e 74 50 74 72 29 29 3b 0a 20 20 20  egmentPtr));.   
b550: 20 70 74 72 2e 70 4c 65 76 65 6c 20 3d 20 70 50   ptr.pLevel = pP
b560: 74 72 2d 3e 70 4c 65 76 65 6c 3b 0a 20 20 20 20  tr->pLevel;.    
b570: 70 74 72 2e 70 53 65 67 20 3d 20 26 70 74 72 2e  ptr.pSeg = &ptr.
b580: 70 4c 65 76 65 6c 2d 3e 61 52 68 73 5b 70 74 72  pLevel->aRhs[ptr
b590: 2e 70 4c 65 76 65 6c 2d 3e 6e 52 69 67 68 74 2d  .pLevel->nRight-
b5a0: 31 5d 3b 0a 20 20 20 20 72 63 20 3d 20 73 6f 72  1];.    rc = sor
b5b0: 74 65 64 52 68 73 46 69 72 73 74 28 70 43 73 72  tedRhsFirst(pCsr
b5c0: 2c 20 70 74 72 2e 70 4c 65 76 65 6c 2c 20 26 70  , ptr.pLevel, &p
b5d0: 74 72 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  tr);.    if( rc=
b5e0: 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  =LSM_OK ){.     
b5f0: 20 72 63 20 3d 20 70 74 72 46 77 64 50 6f 69 6e   rc = ptrFwdPoin
b600: 74 65 72 28 70 74 72 2e 70 50 67 2c 20 70 74 72  ter(ptr.pPg, ptr
b610: 2e 69 43 65 6c 6c 2c 20 70 74 72 2e 70 53 65 67  .iCell, ptr.pSeg
b620: 2c 20 26 69 4f 75 74 2c 20 26 62 46 6f 75 6e 64  , &iOut, &bFound
b630: 29 3b 0a 20 20 20 20 20 20 70 74 72 2e 70 50 67  );.      ptr.pPg
b640: 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20   = 0;.    }.    
b650: 73 65 67 6d 65 6e 74 50 74 72 52 65 73 65 74 28  segmentPtrReset(
b660: 26 70 74 72 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20  &ptr, 0);.  }.. 
b670: 20 2a 70 69 50 74 72 20 3d 20 69 4f 75 74 3b 0a   *piPtr = iOut;.
b680: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
b690: 73 74 61 74 69 63 20 69 6e 74 20 73 65 67 6d 65  static int segme
b6a0: 6e 74 50 74 72 53 65 65 6b 28 0a 20 20 4d 75 6c  ntPtrSeek(.  Mul
b6b0: 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  tiCursor *pCsr, 
b6c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
b6d0: 43 75 72 73 6f 72 20 63 6f 6e 74 65 78 74 20 2a  Cursor context *
b6e0: 2f 0a 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a  /.  SegmentPtr *
b6f0: 70 50 74 72 2c 20 20 20 20 20 20 20 20 20 20 20  pPtr,           
b700: 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
b710: 6f 20 73 65 65 6b 20 2a 2f 0a 20 20 69 6e 74 20  o seek */.  int 
b720: 69 54 6f 70 69 63 2c 20 20 20 20 20 20 20 20 20  iTopic,         
b730: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4b              /* K
b740: 65 79 20 74 6f 70 69 63 20 74 6f 20 73 65 65 6b  ey topic to seek
b750: 20 74 6f 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70   to */.  void *p
b760: 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79 2c 20 20  Key, int nKey,  
b770: 20 20 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 20           /* Key 
b780: 74 6f 20 73 65 65 6b 20 74 6f 20 2a 2f 0a 20 20  to seek to */.  
b790: 69 6e 74 20 65 53 65 65 6b 2c 20 20 20 20 20 20  int eSeek,      
b7a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b7b0: 2f 2a 20 53 65 61 72 63 68 20 62 69 61 73 20 2d  /* Search bias -
b7c0: 20 73 65 65 20 61 62 6f 76 65 20 2a 2f 0a 20 20   see above */.  
b7d0: 69 6e 74 20 2a 70 69 50 74 72 2c 20 20 20 20 20  int *piPtr,     
b7e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b7f0: 2f 2a 20 4f 55 54 3a 20 46 43 20 70 6f 69 6e 74  /* OUT: FC point
b800: 65 72 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 62 53  er */.  int *pbS
b810: 74 6f 70 0a 29 7b 0a 20 20 69 6e 74 20 28 2a 78  top.){.  int (*x
b820: 43 6d 70 29 28 76 6f 69 64 20 2a 2c 20 69 6e 74  Cmp)(void *, int
b830: 2c 20 76 6f 69 64 20 2a 2c 20 69 6e 74 29 20 3d  , void *, int) =
b840: 20 70 43 73 72 2d 3e 70 44 62 2d 3e 78 43 6d 70   pCsr->pDb->xCmp
b850: 3b 0a 20 20 69 6e 74 20 72 65 73 3b 20 20 20 20  ;.  int res;    
b860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b870: 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 6f 66      /* Result of
b880: 20 63 6f 6d 70 61 72 69 73 6f 6e 20 6f 70 65 72   comparison oper
b890: 61 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 72  ation */.  int r
b8a0: 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 69 6e  c = LSM_OK;.  in
b8b0: 74 20 69 4d 69 6e 3b 0a 20 20 69 6e 74 20 69 4d  t iMin;.  int iM
b8c0: 61 78 3b 0a 20 20 50 67 6e 6f 20 69 50 74 72 4f  ax;.  Pgno iPtrO
b8d0: 75 74 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 49 66  ut = 0;..  /* If
b8e0: 20 74 68 65 20 63 75 72 72 65 6e 74 20 70 61 67   the current pag
b8f0: 65 20 63 6f 6e 74 61 69 6e 73 20 61 6e 20 6f 76  e contains an ov
b900: 65 72 73 69 7a 65 64 20 65 6e 74 72 79 2c 20 74  ersized entry, t
b910: 68 65 6e 20 74 68 65 72 65 20 61 72 65 20 6e 6f  hen there are no
b920: 0a 20 20 2a 2a 20 70 6f 69 6e 74 65 72 73 20 74  .  ** pointers t
b930: 6f 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 6f 66  o one or more of
b940: 20 74 68 65 20 73 75 62 73 65 71 75 65 6e 74 20   the subsequent 
b950: 70 61 67 65 73 20 69 6e 20 74 68 65 20 73 6f 72  pages in the sor
b960: 74 65 64 20 72 75 6e 2e 0a 20 20 2a 2a 20 54 68  ted run..  ** Th
b970: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 61 6c 6c  e following call
b980: 20 65 6e 73 75 72 65 73 20 74 68 61 74 20 74 68   ensures that th
b990: 65 20 73 65 67 6d 65 6e 74 2d 70 74 72 20 70 6f  e segment-ptr po
b9a0: 69 6e 74 73 20 74 6f 20 74 68 65 20 63 6f 72 72  ints to the corr
b9b0: 65 63 74 20 0a 20 20 2a 2a 20 70 61 67 65 20 69  ect .  ** page i
b9c0: 6e 20 74 68 69 73 20 63 61 73 65 2e 20 20 2a 2f  n this case.  */
b9d0: 0a 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50  .  rc = segmentP
b9e0: 74 72 53 65 61 72 63 68 4f 76 65 72 73 69 7a 65  trSearchOversize
b9f0: 64 28 70 43 73 72 2c 20 70 50 74 72 2c 20 69 54  d(pCsr, pPtr, iT
ba00: 6f 70 69 63 2c 20 70 4b 65 79 2c 20 6e 4b 65 79  opic, pKey, nKey
ba10: 29 3b 0a 20 20 69 50 74 72 4f 75 74 20 3d 20 70  );.  iPtrOut = p
ba20: 50 74 72 2d 3e 69 50 74 72 3b 0a 0a 20 20 2f 2a  Ptr->iPtr;..  /*
ba30: 20 41 73 73 65 72 74 20 74 68 61 74 20 74 68 69   Assert that thi
ba40: 73 20 70 61 67 65 20 69 73 20 74 68 65 20 72 69  s page is the ri
ba50: 67 68 74 20 70 61 67 65 20 6f 66 20 74 68 69 73  ght page of this
ba60: 20 73 65 67 6d 65 6e 74 20 66 6f 72 20 74 68 65   segment for the
ba70: 20 6b 65 79 0a 20 20 2a 2a 20 74 68 61 74 20 77   key.  ** that w
ba80: 65 20 61 72 65 20 73 65 61 72 63 68 69 6e 67 20  e are searching 
ba90: 66 6f 72 2e 20 44 6f 20 74 68 69 73 20 62 79 20  for. Do this by 
baa0: 6c 6f 61 64 69 6e 67 20 70 61 67 65 20 28 69 50  loading page (iP
bab0: 67 2d 31 29 20 61 6e 64 20 74 65 73 74 69 6e 67  g-1) and testing
bac0: 0a 20 20 2a 2a 20 74 68 61 74 20 70 4b 65 79 2f  .  ** that pKey/
bad0: 6e 4b 65 79 20 69 73 20 67 72 65 61 74 65 72 20  nKey is greater 
bae0: 74 68 61 6e 20 61 6c 6c 20 6b 65 79 73 20 6f 6e  than all keys on
baf0: 20 74 68 61 74 20 70 61 67 65 2c 20 61 6e 64 20   that page, and 
bb00: 74 68 65 6e 20 62 79 20 0a 20 20 2a 2a 20 6c 6f  then by .  ** lo
bb10: 61 64 69 6e 67 20 28 69 50 67 2b 31 29 20 61 6e  ading (iPg+1) an
bb20: 64 20 74 65 73 74 69 6e 67 20 74 68 61 74 20 70  d testing that p
bb30: 4b 65 79 2f 6e 4b 65 79 20 69 73 20 73 6d 61 6c  Key/nKey is smal
bb40: 6c 65 72 20 74 68 61 6e 20 61 6c 6c 0a 20 20 2a  ler than all.  *
bb50: 2a 20 74 68 65 20 6b 65 79 73 20 69 74 20 68 6f  * the keys it ho
bb60: 75 73 65 73 2e 20 20 0a 20 20 2a 2a 0a 20 20 2a  uses.  .  **.  *
bb70: 2a 20 54 4f 44 4f 3a 20 57 69 74 68 20 72 61 6e  * TODO: With ran
bb80: 67 65 2d 64 65 6c 65 74 65 73 20 69 6e 20 74 68  ge-deletes in th
bb90: 65 20 74 72 65 65 2c 20 74 68 65 20 74 65 73 74  e tree, the test
bba0: 20 64 65 73 63 72 69 62 65 64 20 61 62 6f 76 65   described above
bbb0: 20 6d 61 79 20 66 61 69 6c 2e 0a 20 20 2a 2f 0a   may fail..  */.
bbc0: 23 69 66 20 30 0a 20 20 61 73 73 65 72 74 28 20  #if 0.  assert( 
bbd0: 61 73 73 65 72 74 4b 65 79 4c 6f 63 61 74 69 6f  assertKeyLocatio
bbe0: 6e 28 70 43 73 72 2c 20 70 50 74 72 2c 20 70 4b  n(pCsr, pPtr, pK
bbf0: 65 79 2c 20 6e 4b 65 79 29 20 29 3b 0a 23 65 6e  ey, nKey) );.#en
bc00: 64 69 66 0a 0a 20 20 61 73 73 65 72 74 28 20 70  dif..  assert( p
bc10: 50 74 72 2d 3e 6e 43 65 6c 6c 3e 30 20 0a 20 20  Ptr->nCell>0 .  
bc20: 20 20 20 20 20 7c 7c 20 70 50 74 72 2d 3e 70 53       || pPtr->pS
bc30: 65 67 2d 3e 6e 53 69 7a 65 3d 3d 31 20 0a 20 20  eg->nSize==1 .  
bc40: 20 20 20 20 20 7c 7c 20 6c 73 6d 46 73 44 62 50       || lsmFsDbP
bc50: 61 67 65 49 73 4c 61 73 74 28 70 50 74 72 2d 3e  ageIsLast(pPtr->
bc60: 70 53 65 67 2c 20 70 50 74 72 2d 3e 70 50 67 29  pSeg, pPtr->pPg)
bc70: 0a 20 20 29 3b 0a 20 20 69 66 28 20 70 50 74 72  .  );.  if( pPtr
bc80: 2d 3e 6e 43 65 6c 6c 3d 3d 30 20 29 7b 0a 20 20  ->nCell==0 ){.  
bc90: 20 20 73 65 67 6d 65 6e 74 50 74 72 52 65 73 65    segmentPtrRese
bca0: 74 28 70 50 74 72 2c 20 4c 53 4d 5f 53 45 47 4d  t(pPtr, LSM_SEGM
bcb0: 45 4e 54 50 54 52 5f 46 52 45 45 5f 54 48 52 45  ENTPTR_FREE_THRE
bcc0: 53 48 4f 4c 44 29 3b 0a 20 20 7d 65 6c 73 65 7b  SHOLD);.  }else{
bcd0: 0a 20 20 20 20 69 4d 69 6e 20 3d 20 30 3b 0a 20  .    iMin = 0;. 
bce0: 20 20 20 69 4d 61 78 20 3d 20 70 50 74 72 2d 3e     iMax = pPtr->
bcf0: 6e 43 65 6c 6c 2d 31 3b 0a 0a 20 20 20 20 77 68  nCell-1;..    wh
bd00: 69 6c 65 28 20 31 20 29 7b 0a 20 20 20 20 20 20  ile( 1 ){.      
bd10: 69 6e 74 20 69 54 72 79 20 3d 20 28 69 4d 69 6e  int iTry = (iMin
bd20: 2b 69 4d 61 78 29 2f 32 3b 0a 20 20 20 20 20 20  +iMax)/2;.      
bd30: 76 6f 69 64 20 2a 70 4b 65 79 54 3b 20 69 6e 74  void *pKeyT; int
bd40: 20 6e 4b 65 79 54 3b 20 20 20 20 20 20 20 2f 2a   nKeyT;       /*
bd50: 20 4b 65 79 20 66 6f 72 20 63 65 6c 6c 20 69 54   Key for cell iT
bd60: 72 79 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20  ry */.      int 
bd70: 69 54 6f 70 69 63 54 3b 0a 0a 20 20 20 20 20 20  iTopicT;..      
bd80: 61 73 73 65 72 74 28 20 69 54 72 79 3c 69 4d 61  assert( iTry<iMa
bd90: 78 20 7c 7c 20 69 4d 69 6e 3d 3d 69 4d 61 78 20  x || iMin==iMax 
bda0: 29 3b 0a 0a 20 20 20 20 20 20 72 63 20 3d 20 73  );..      rc = s
bdb0: 65 67 6d 65 6e 74 50 74 72 4c 6f 61 64 43 65 6c  egmentPtrLoadCel
bdc0: 6c 28 70 50 74 72 2c 20 69 54 72 79 29 3b 0a 20  l(pPtr, iTry);. 
bdd0: 20 20 20 20 20 69 66 28 20 72 63 21 3d 4c 53 4d       if( rc!=LSM
bde0: 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 0a 20 20  _OK ) break;..  
bdf0: 20 20 20 20 73 65 67 6d 65 6e 74 50 74 72 4b 65      segmentPtrKe
be00: 79 28 70 50 74 72 2c 20 26 70 4b 65 79 54 2c 20  y(pPtr, &pKeyT, 
be10: 26 6e 4b 65 79 54 29 3b 0a 20 20 20 20 20 20 69  &nKeyT);.      i
be20: 54 6f 70 69 63 54 20 3d 20 72 74 54 6f 70 69 63  TopicT = rtTopic
be30: 28 70 50 74 72 2d 3e 65 54 79 70 65 29 3b 0a 0a  (pPtr->eType);..
be40: 20 20 20 20 20 20 72 65 73 20 3d 20 73 6f 72 74        res = sort
be50: 65 64 4b 65 79 43 6f 6d 70 61 72 65 28 78 43 6d  edKeyCompare(xCm
be60: 70 2c 20 69 54 6f 70 69 63 54 2c 20 70 4b 65 79  p, iTopicT, pKey
be70: 54 2c 20 6e 4b 65 79 54 2c 20 69 54 6f 70 69 63  T, nKeyT, iTopic
be80: 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 20  , pKey, nKey);. 
be90: 20 20 20 20 20 69 66 28 20 72 65 73 3c 3d 30 20       if( res<=0 
bea0: 29 7b 0a 20 20 20 20 20 20 20 20 69 50 74 72 4f  ){.        iPtrO
beb0: 75 74 20 3d 20 70 50 74 72 2d 3e 69 50 74 72 20  ut = pPtr->iPtr 
bec0: 2b 20 70 50 74 72 2d 3e 69 50 67 50 74 72 3b 0a  + pPtr->iPgPtr;.
bed0: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 69        }..      i
bee0: 66 28 20 72 65 73 3d 3d 30 20 7c 7c 20 69 4d 69  f( res==0 || iMi
bef0: 6e 3d 3d 69 4d 61 78 20 29 7b 0a 20 20 20 20 20  n==iMax ){.     
bf00: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
bf10: 7d 65 6c 73 65 20 69 66 28 20 72 65 73 3e 30 20  }else if( res>0 
bf20: 29 7b 0a 20 20 20 20 20 20 20 20 69 4d 61 78 20  ){.        iMax 
bf30: 3d 20 4c 53 4d 5f 4d 41 58 28 69 54 72 79 2d 31  = LSM_MAX(iTry-1
bf40: 2c 20 69 4d 69 6e 29 3b 0a 20 20 20 20 20 20 7d  , iMin);.      }
bf50: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69 4d  else{.        iM
bf60: 69 6e 20 3d 20 69 54 72 79 2b 31 3b 0a 20 20 20  in = iTry+1;.   
bf70: 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20     }.    }..    
bf80: 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
bf90: 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  {.      assert( 
bfa0: 72 65 73 3d 3d 30 20 7c 7c 20 28 69 4d 69 6e 3d  res==0 || (iMin=
bfb0: 3d 69 4d 61 78 20 26 26 20 69 4d 69 6e 3e 3d 30  =iMax && iMin>=0
bfc0: 20 26 26 20 69 4d 69 6e 3c 70 50 74 72 2d 3e 6e   && iMin<pPtr->n
bfd0: 43 65 6c 6c 29 20 29 3b 0a 20 20 20 20 20 20 69  Cell) );.      i
bfe0: 66 28 20 72 65 73 20 29 7b 0a 20 20 20 20 20 20  f( res ){.      
bff0: 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74    rc = segmentPt
c000: 72 4c 6f 61 64 43 65 6c 6c 28 70 50 74 72 2c 20  rLoadCell(pPtr, 
c010: 69 4d 69 6e 29 3b 0a 20 20 20 20 20 20 7d 0a 20  iMin);.      }. 
c020: 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21       assert( rc!
c030: 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 72 65 73 3e 30  =LSM_OK || res>0
c040: 20 7c 7c 20 69 50 74 72 4f 75 74 3d 3d 28 70 50   || iPtrOut==(pP
c050: 74 72 2d 3e 69 50 74 72 20 2b 20 70 50 74 72 2d  tr->iPtr + pPtr-
c060: 3e 69 50 67 50 74 72 29 20 29 3b 0a 0a 20 20 20  >iPgPtr) );..   
c070: 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
c080: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 73 77 69  K ){.        swi
c090: 74 63 68 28 20 65 53 65 65 6b 20 29 7b 0a 20 20  tch( eSeek ){.  
c0a0: 20 20 20 20 20 20 20 20 63 61 73 65 20 4c 53 4d          case LSM
c0b0: 5f 53 45 45 4b 5f 45 51 3a 20 7b 0a 20 20 20 20  _SEEK_EQ: {.    
c0c0: 20 20 20 20 20 20 20 20 69 6e 74 20 65 54 79 70          int eTyp
c0d0: 65 20 3d 20 70 50 74 72 2d 3e 65 54 79 70 65 3b  e = pPtr->eType;
c0e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28  .            if(
c0f0: 20 28 72 65 73 3c 30 20 26 26 20 28 65 54 79 70   (res<0 && (eTyp
c100: 65 20 26 20 4c 53 4d 5f 53 54 41 52 54 5f 44 45  e & LSM_START_DE
c110: 4c 45 54 45 29 29 0a 20 20 20 20 20 20 20 20 20  LETE)).         
c120: 20 20 20 20 7c 7c 20 28 72 65 73 3e 30 20 26 26      || (res>0 &&
c130: 20 28 65 54 79 70 65 20 26 20 4c 53 4d 5f 45 4e   (eType & LSM_EN
c140: 44 5f 44 45 4c 45 54 45 29 29 0a 20 20 20 20 20  D_DELETE)).     
c150: 20 20 20 20 20 20 20 20 7c 7c 20 28 72 65 73 3d          || (res=
c160: 3d 30 20 26 26 20 28 65 54 79 70 65 20 26 20 4c  =0 && (eType & L
c170: 53 4d 5f 50 4f 49 4e 54 5f 44 45 4c 45 54 45 29  SM_POINT_DELETE)
c180: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 29 7b  ).            ){
c190: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a  .              *
c1a0: 70 62 53 74 6f 70 20 3d 20 31 3b 0a 20 20 20 20  pbStop = 1;.    
c1b0: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66          }else if
c1c0: 28 20 72 65 73 3d 3d 30 20 26 26 20 28 65 54 79  ( res==0 && (eTy
c1d0: 70 65 20 26 20 4c 53 4d 5f 49 4e 53 45 52 54 29  pe & LSM_INSERT)
c1e0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
c1f0: 20 20 6c 73 6d 5f 65 6e 76 20 2a 70 45 6e 76 20    lsm_env *pEnv 
c200: 3d 20 70 43 73 72 2d 3e 70 44 62 2d 3e 70 45 6e  = pCsr->pDb->pEn
c210: 76 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  v;.             
c220: 20 2a 70 62 53 74 6f 70 20 3d 20 31 3b 0a 20 20   *pbStop = 1;.  
c230: 20 20 20 20 20 20 20 20 20 20 20 20 70 43 73 72              pCsr
c240: 2d 3e 65 54 79 70 65 20 3d 20 70 50 74 72 2d 3e  ->eType = pPtr->
c250: 65 54 79 70 65 3b 0a 20 20 20 20 20 20 20 20 20  eType;.         
c260: 20 20 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64       rc = sorted
c270: 42 6c 6f 62 53 65 74 28 70 45 6e 76 2c 20 26 70  BlobSet(pEnv, &p
c280: 43 73 72 2d 3e 6b 65 79 2c 20 70 50 74 72 2d 3e  Csr->key, pPtr->
c290: 70 4b 65 79 2c 20 70 50 74 72 2d 3e 6e 4b 65 79  pKey, pPtr->nKey
c2a0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  );.             
c2b0: 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
c2c0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ){.             
c2d0: 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64 42 6c     rc = sortedBl
c2e0: 6f 62 53 65 74 28 70 45 6e 76 2c 20 26 70 43 73  obSet(pEnv, &pCs
c2f0: 72 2d 3e 76 61 6c 2c 20 70 50 74 72 2d 3e 70 56  r->val, pPtr->pV
c300: 61 6c 2c 20 70 50 74 72 2d 3e 6e 56 61 6c 29 3b  al, pPtr->nVal);
c310: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d  .              }
c320: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70  .              p
c330: 43 73 72 2d 3e 66 6c 61 67 73 20 7c 3d 20 43 55  Csr->flags |= CU
c340: 52 53 4f 52 5f 53 45 45 4b 5f 45 51 3b 0a 20 20  RSOR_SEEK_EQ;.  
c350: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
c360: 20 20 20 20 20 20 20 20 73 65 67 6d 65 6e 74 50          segmentP
c370: 74 72 52 65 73 65 74 28 70 50 74 72 2c 20 4c 53  trReset(pPtr, LS
c380: 4d 5f 53 45 47 4d 45 4e 54 50 54 52 5f 46 52 45  M_SEGMENTPTR_FRE
c390: 45 5f 54 48 52 45 53 48 4f 4c 44 29 3b 0a 20 20  E_THRESHOLD);.  
c3a0: 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
c3b0: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
c3c0: 20 20 20 20 20 20 20 63 61 73 65 20 4c 53 4d 5f         case LSM_
c3d0: 53 45 45 4b 5f 4c 45 3a 0a 20 20 20 20 20 20 20  SEEK_LE:.       
c3e0: 20 20 20 20 20 69 66 28 20 72 65 73 3e 30 20 29       if( res>0 )
c3f0: 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74 72   rc = segmentPtr
c400: 41 64 76 61 6e 63 65 28 70 43 73 72 2c 20 70 50  Advance(pCsr, pP
c410: 74 72 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20  tr, 1);.        
c420: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
c430: 20 20 20 20 20 63 61 73 65 20 4c 53 4d 5f 53 45       case LSM_SE
c440: 45 4b 5f 47 45 3a 20 7b 0a 20 20 20 20 20 20 20  EK_GE: {.       
c450: 20 20 20 20 20 2f 2a 20 46 69 67 75 72 65 20 6f       /* Figure o
c460: 75 74 20 69 66 20 77 65 20 6e 65 65 64 20 74 6f  ut if we need to
c470: 20 27 73 6b 69 70 27 20 74 68 65 20 70 6f 69 6e   'skip' the poin
c480: 74 65 72 20 66 6f 72 77 61 72 64 20 6f 72 20 6e  ter forward or n
c490: 6f 74 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  ot */.          
c4a0: 20 20 69 66 28 20 28 72 65 73 3c 3d 30 20 26 26    if( (res<=0 &&
c4b0: 20 28 70 50 74 72 2d 3e 65 54 79 70 65 20 26 20   (pPtr->eType & 
c4c0: 4c 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45 54 45  LSM_START_DELETE
c4d0: 29 29 20 0a 20 20 20 20 20 20 20 20 20 20 20 20  )) .            
c4e0: 20 7c 7c 20 28 72 65 73 3e 30 20 20 26 26 20 28   || (res>0  && (
c4f0: 70 50 74 72 2d 3e 65 54 79 70 65 20 26 20 4c 53  pPtr->eType & LS
c500: 4d 5f 45 4e 44 5f 44 45 4c 45 54 45 29 29 20 0a  M_END_DELETE)) .
c510: 20 20 20 20 20 20 20 20 20 20 20 20 29 7b 0a 20              ){. 
c520: 20 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20               rc 
c530: 3d 20 73 65 67 6d 65 6e 74 50 74 72 46 77 64 50  = segmentPtrFwdP
c540: 6f 69 6e 74 65 72 28 70 43 73 72 2c 20 70 50 74  ointer(pCsr, pPt
c550: 72 2c 20 26 69 50 74 72 4f 75 74 29 3b 0a 20 20  r, &iPtrOut);.  
c560: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
c570: 20 20 20 20 20 20 20 20 69 66 28 20 72 65 73 3c          if( res<
c580: 30 20 26 26 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20  0 && rc==LSM_OK 
c590: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ){.             
c5a0: 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74 72   rc = segmentPtr
c5b0: 41 64 76 61 6e 63 65 28 70 43 73 72 2c 20 70 50  Advance(pCsr, pP
c5c0: 74 72 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20  tr, 0);.        
c5d0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20      }.          
c5e0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20    break;.       
c5f0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20     }.        }. 
c600: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
c610: 20 20 2f 2a 20 49 66 20 74 68 65 20 63 75 72 73    /* If the curs
c620: 6f 72 20 73 65 65 6b 20 68 61 73 20 66 6f 75 6e  or seek has foun
c630: 64 20 61 20 73 65 70 61 72 61 74 6f 72 20 6b 65  d a separator ke
c640: 79 2c 20 61 6e 64 20 74 68 69 73 20 63 75 72 73  y, and this curs
c650: 6f 72 20 69 73 0a 20 20 20 20 2a 2a 20 73 75 70  or is.    ** sup
c660: 70 6f 73 65 64 20 74 6f 20 69 67 6e 6f 72 65 20  posed to ignore 
c670: 73 65 70 61 72 61 74 6f 72 73 20 6b 65 79 73 2c  separators keys,
c680: 20 61 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20   advance to the 
c690: 6e 65 78 74 20 65 6e 74 72 79 2e 20 20 2a 2f 0a  next entry.  */.
c6a0: 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f      if( rc==LSM_
c6b0: 4f 4b 20 26 26 20 70 50 74 72 2d 3e 70 50 67 0a  OK && pPtr->pPg.
c6c0: 20 20 20 20 20 26 26 20 73 65 67 6d 65 6e 74 50       && segmentP
c6d0: 74 72 49 67 6e 6f 72 65 53 65 70 61 72 61 74 6f  trIgnoreSeparato
c6e0: 72 73 28 70 43 73 72 2c 20 70 50 74 72 29 20 0a  rs(pCsr, pPtr) .
c6f0: 20 20 20 20 20 26 26 20 72 74 49 73 53 65 70 61       && rtIsSepa
c700: 72 61 74 6f 72 28 70 50 74 72 2d 3e 65 54 79 70  rator(pPtr->eTyp
c710: 65 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20  e).    ){.      
c720: 61 73 73 65 72 74 28 20 65 53 65 65 6b 21 3d 4c  assert( eSeek!=L
c730: 53 4d 5f 53 45 45 4b 5f 45 51 20 29 3b 0a 20 20  SM_SEEK_EQ );.  
c740: 20 20 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74      rc = segment
c750: 50 74 72 41 64 76 61 6e 63 65 28 70 43 73 72 2c  PtrAdvance(pCsr,
c760: 20 70 50 74 72 2c 20 65 53 65 65 6b 3d 3d 4c 53   pPtr, eSeek==LS
c770: 4d 5f 53 45 45 4b 5f 4c 45 29 3b 0a 20 20 20 20  M_SEEK_LE);.    
c780: 7d 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28  }.  }..  assert(
c790: 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 61   rc!=LSM_OK || a
c7a0: 73 73 65 72 74 53 65 65 6b 52 65 73 75 6c 74 28  ssertSeekResult(
c7b0: 70 43 73 72 2c 70 50 74 72 2c 69 54 6f 70 69 63  pCsr,pPtr,iTopic
c7c0: 2c 70 4b 65 79 2c 6e 4b 65 79 2c 65 53 65 65 6b  ,pKey,nKey,eSeek
c7d0: 29 20 29 3b 0a 20 20 2a 70 69 50 74 72 20 3d 20  ) );.  *piPtr = 
c7e0: 69 50 74 72 4f 75 74 3b 0a 20 20 72 65 74 75 72  iPtrOut;.  retur
c7f0: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
c800: 69 6e 74 20 73 65 65 6b 49 6e 42 74 72 65 65 28  int seekInBtree(
c810: 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a  .  MultiCursor *
c820: 70 43 73 72 2c 20 20 20 20 20 20 20 20 20 20 20  pCsr,           
c830: 20 20 20 2f 2a 20 4d 75 6c 74 69 2d 63 75 72 73     /* Multi-curs
c840: 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 53  or object */.  S
c850: 65 67 6d 65 6e 74 20 2a 70 53 65 67 2c 20 20 20  egment *pSeg,   
c860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c870: 2a 20 53 65 65 6b 20 77 69 74 68 69 6e 20 74 68  * Seek within th
c880: 69 73 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 20 20  is segment */.  
c890: 69 6e 74 20 69 54 6f 70 69 63 2c 0a 20 20 76 6f  int iTopic,.  vo
c8a0: 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b  id *pKey, int nK
c8b0: 65 79 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ey,           /*
c8c0: 20 4b 65 79 20 74 6f 20 73 65 65 6b 20 74 6f 20   Key to seek to 
c8d0: 2a 2f 0a 20 20 50 67 6e 6f 20 2a 61 50 67 2c 20  */.  Pgno *aPg, 
c8e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c8f0: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50 61 67       /* OUT: Pag
c900: 65 20 6e 75 6d 62 65 72 73 20 2a 2f 0a 20 20 50  e numbers */.  P
c910: 61 67 65 20 2a 2a 70 70 50 67 20 20 20 20 20 20  age **ppPg      
c920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c930: 2a 20 4f 55 54 3a 20 4c 65 61 66 20 28 73 6f 72  * OUT: Leaf (sor
c940: 74 65 64 2d 72 75 6e 29 20 70 61 67 65 20 72 65  ted-run) page re
c950: 66 65 72 65 6e 63 65 20 2a 2f 0a 29 7b 0a 20 20  ference */.){.  
c960: 69 6e 74 20 69 20 3d 20 30 3b 0a 20 20 69 6e 74  int i = 0;.  int
c970: 20 72 63 3b 0a 20 20 69 6e 74 20 69 50 67 3b 0a   rc;.  int iPg;.
c980: 20 20 50 61 67 65 20 2a 70 50 67 20 3d 20 30 3b    Page *pPg = 0;
c990: 0a 20 20 42 6c 6f 62 20 62 6c 6f 62 20 3d 20 7b  .  Blob blob = {
c9a0: 30 2c 20 30 2c 20 30 7d 3b 0a 0a 20 20 69 50 67  0, 0, 0};..  iPg
c9b0: 20 3d 20 70 53 65 67 2d 3e 69 52 6f 6f 74 3b 0a   = pSeg->iRoot;.
c9c0: 20 20 64 6f 20 7b 0a 20 20 20 20 50 67 6e 6f 20    do {.    Pgno 
c9d0: 2a 70 69 46 69 72 73 74 20 3d 20 30 3b 0a 20 20  *piFirst = 0;.  
c9e0: 20 20 69 66 28 20 61 50 67 20 29 7b 0a 20 20 20    if( aPg ){.   
c9f0: 20 20 20 61 50 67 5b 69 2b 2b 5d 20 3d 20 69 50     aPg[i++] = iP
ca00: 67 3b 0a 20 20 20 20 20 20 70 69 46 69 72 73 74  g;.      piFirst
ca10: 20 3d 20 26 61 50 67 5b 69 5d 3b 0a 20 20 20 20   = &aPg[i];.    
ca20: 7d 0a 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 46  }..    rc = lsmF
ca30: 73 44 62 50 61 67 65 47 65 74 28 70 43 73 72 2d  sDbPageGet(pCsr-
ca40: 3e 70 44 62 2d 3e 70 46 53 2c 20 70 53 65 67 2c  >pDb->pFS, pSeg,
ca50: 20 69 50 67 2c 20 26 70 50 67 29 3b 0a 20 20 20   iPg, &pPg);.   
ca60: 20 61 73 73 65 72 74 28 20 72 63 3d 3d 4c 53 4d   assert( rc==LSM
ca70: 5f 4f 4b 20 7c 7c 20 70 50 67 3d 3d 30 20 29 3b  _OK || pPg==0 );
ca80: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d  .    if( rc==LSM
ca90: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 75 38 20  _OK ){.      u8 
caa0: 2a 61 44 61 74 61 3b 20 20 20 20 20 20 20 20 20  *aData;         
cab0: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66           /* Buff
cac0: 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 70 61  er containing pa
cad0: 67 65 20 64 61 74 61 20 2a 2f 0a 20 20 20 20 20  ge data */.     
cae0: 20 69 6e 74 20 6e 44 61 74 61 3b 20 20 20 20 20   int nData;     
caf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
cb00: 53 69 7a 65 20 6f 66 20 61 44 61 74 61 5b 5d 20  Size of aData[] 
cb10: 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 20 20  in bytes */.    
cb20: 20 20 69 6e 74 20 69 4d 69 6e 3b 0a 20 20 20 20    int iMin;.    
cb30: 20 20 69 6e 74 20 69 4d 61 78 3b 0a 20 20 20 20    int iMax;.    
cb40: 20 20 69 6e 74 20 6e 52 65 63 3b 0a 20 20 20 20    int nRec;.    
cb50: 20 20 69 6e 74 20 66 6c 61 67 73 3b 0a 0a 20 20    int flags;..  
cb60: 20 20 20 20 61 44 61 74 61 20 3d 20 66 73 50 61      aData = fsPa
cb70: 67 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44 61  geData(pPg, &nDa
cb80: 74 61 29 3b 0a 20 20 20 20 20 20 66 6c 61 67 73  ta);.      flags
cb90: 20 3d 20 70 61 67 65 47 65 74 46 6c 61 67 73 28   = pageGetFlags(
cba0: 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20  aData, nData);. 
cbb0: 20 20 20 20 20 69 66 28 20 28 66 6c 61 67 73 20       if( (flags 
cbc0: 26 20 53 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f  & SEGMENT_BTREE_
cbd0: 46 4c 41 47 29 3d 3d 30 20 29 20 62 72 65 61 6b  FLAG)==0 ) break
cbe0: 3b 0a 0a 20 20 20 20 20 20 69 50 67 20 3d 20 70  ;..      iPg = p
cbf0: 61 67 65 47 65 74 50 74 72 28 61 44 61 74 61 2c  ageGetPtr(aData,
cc00: 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20 6e   nData);.      n
cc10: 52 65 63 20 3d 20 70 61 67 65 47 65 74 4e 52 65  Rec = pageGetNRe
cc20: 63 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b  c(aData, nData);
cc30: 0a 0a 20 20 20 20 20 20 69 4d 69 6e 20 3d 20 30  ..      iMin = 0
cc40: 3b 0a 20 20 20 20 20 20 69 4d 61 78 20 3d 20 6e  ;.      iMax = n
cc50: 52 65 63 2d 31 3b 0a 20 20 20 20 20 20 77 68 69  Rec-1;.      whi
cc60: 6c 65 28 20 69 4d 61 78 3e 3d 69 4d 69 6e 20 29  le( iMax>=iMin )
cc70: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 54  {.        int iT
cc80: 72 79 20 3d 20 28 69 4d 69 6e 2b 69 4d 61 78 29  ry = (iMin+iMax)
cc90: 2f 32 3b 0a 20 20 20 20 20 20 20 20 76 6f 69 64  /2;.        void
cca0: 20 2a 70 4b 65 79 54 3b 20 69 6e 74 20 6e 4b 65   *pKeyT; int nKe
ccb0: 79 54 3b 20 20 20 20 20 20 20 2f 2a 20 4b 65 79  yT;       /* Key
ccc0: 20 66 6f 72 20 63 65 6c 6c 20 69 54 72 79 20 2a   for cell iTry *
ccd0: 2f 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 54  /.        int iT
cce0: 6f 70 69 63 54 3b 20 20 20 20 20 20 20 20 20 20  opicT;          
ccf0: 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 70 69 63          /* Topic
cd00: 20 66 6f 72 20 6b 65 79 20 70 4b 65 79 54 2f 6e   for key pKeyT/n
cd10: 4b 65 79 54 20 2a 2f 0a 20 20 20 20 20 20 20 20  KeyT */.        
cd20: 50 67 6e 6f 20 69 50 74 72 3b 20 20 20 20 20 20  Pgno iPtr;      
cd30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
cd40: 20 50 6f 69 6e 74 65 72 20 61 73 73 6f 63 69 61   Pointer associa
cd50: 74 65 64 20 77 69 74 68 20 63 65 6c 6c 20 69 54  ted with cell iT
cd60: 72 79 20 2a 2f 0a 20 20 20 20 20 20 20 20 69 6e  ry */.        in
cd70: 74 20 72 65 73 3b 20 20 20 20 20 20 20 20 20 20  t res;          
cd80: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 28              /* (
cd90: 70 4b 65 79 20 2d 20 70 4b 65 79 54 29 20 2a 2f  pKey - pKeyT) */
cda0: 0a 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70  ..        rc = p
cdb0: 61 67 65 47 65 74 42 74 72 65 65 4b 65 79 28 0a  ageGetBtreeKey(.
cdc0: 20 20 20 20 20 20 20 20 20 20 20 20 70 53 65 67              pSeg
cdd0: 2c 20 70 50 67 2c 20 69 54 72 79 2c 20 26 69 50  , pPg, iTry, &iP
cde0: 74 72 2c 20 26 69 54 6f 70 69 63 54 2c 20 26 70  tr, &iTopicT, &p
cdf0: 4b 65 79 54 2c 20 26 6e 4b 65 79 54 2c 20 26 62  KeyT, &nKeyT, &b
ce00: 6c 6f 62 0a 20 20 20 20 20 20 20 20 29 3b 0a 20  lob.        );. 
ce10: 20 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 4c         if( rc!=L
ce20: 53 4d 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20  SM_OK ) break;. 
ce30: 20 20 20 20 20 20 20 69 66 28 20 70 69 46 69 72         if( piFir
ce40: 73 74 20 26 26 20 70 4b 65 79 54 3d 3d 62 6c 6f  st && pKeyT==blo
ce50: 62 2e 70 44 61 74 61 20 29 7b 0a 20 20 20 20 20  b.pData ){.     
ce60: 20 20 20 20 20 2a 70 69 46 69 72 73 74 20 3d 20       *piFirst = 
ce70: 70 61 67 65 47 65 74 42 74 72 65 65 52 65 66 28  pageGetBtreeRef(
ce80: 70 50 67 2c 20 69 54 72 79 29 3b 0a 20 20 20 20  pPg, iTry);.    
ce90: 20 20 20 20 20 20 70 69 46 69 72 73 74 20 3d 20        piFirst = 
cea0: 30 3b 0a 20 20 20 20 20 20 20 20 20 20 69 2b 2b  0;.          i++
ceb0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20  ;.        }..   
cec0: 20 20 20 20 20 72 65 73 20 3d 20 73 6f 72 74 65       res = sorte
ced0: 64 4b 65 79 43 6f 6d 70 61 72 65 28 0a 20 20 20  dKeyCompare(.   
cee0: 20 20 20 20 20 20 20 20 20 70 43 73 72 2d 3e 70           pCsr->p
cef0: 44 62 2d 3e 78 43 6d 70 2c 20 69 54 6f 70 69 63  Db->xCmp, iTopic
cf00: 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 2c 20 69 54  , pKey, nKey, iT
cf10: 6f 70 69 63 54 2c 20 70 4b 65 79 54 2c 20 6e 4b  opicT, pKeyT, nK
cf20: 65 79 54 0a 20 20 20 20 20 20 20 20 29 3b 0a 20  eyT.        );. 
cf30: 20 20 20 20 20 20 20 69 66 28 20 72 65 73 3c 30         if( res<0
cf40: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 50   ){.          iP
cf50: 67 20 3d 20 69 50 74 72 3b 0a 20 20 20 20 20 20  g = iPtr;.      
cf60: 20 20 20 20 69 4d 61 78 20 3d 20 69 54 72 79 2d      iMax = iTry-
cf70: 31 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65  1;.        }else
cf80: 7b 0a 20 20 20 20 20 20 20 20 20 20 69 4d 69 6e  {.          iMin
cf90: 20 3d 20 69 54 72 79 2b 31 3b 0a 20 20 20 20 20   = iTry+1;.     
cfa0: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
cfb0: 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65     lsmFsPageRele
cfc0: 61 73 65 28 70 50 67 29 3b 0a 20 20 20 20 20 20  ase(pPg);.      
cfd0: 70 50 67 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20  pPg = 0;.    }. 
cfe0: 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d   }while( rc==LSM
cff0: 5f 4f 4b 20 29 3b 0a 0a 20 20 73 6f 72 74 65 64  _OK );..  sorted
d000: 42 6c 6f 62 46 72 65 65 28 26 62 6c 6f 62 29 3b  BlobFree(&blob);
d010: 0a 20 20 61 73 73 65 72 74 28 20 28 72 63 3d 3d  .  assert( (rc==
d020: 4c 53 4d 5f 4f 4b 29 3d 3d 28 70 50 67 21 3d 30  LSM_OK)==(pPg!=0
d030: 29 20 29 3b 0a 20 20 69 66 28 20 70 70 50 67 20  ) );.  if( ppPg 
d040: 29 7b 0a 20 20 20 20 2a 70 70 50 67 20 3d 20 70  ){.    *ppPg = p
d050: 50 67 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  Pg;.  }else{.   
d060: 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61 73   lsmFsPageReleas
d070: 65 28 70 50 67 29 3b 0a 20 20 7d 0a 20 20 72 65  e(pPg);.  }.  re
d080: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
d090: 69 63 20 69 6e 74 20 73 65 65 6b 49 6e 53 65 67  ic int seekInSeg
d0a0: 6d 65 6e 74 28 0a 20 20 4d 75 6c 74 69 43 75 72  ment(.  MultiCur
d0b0: 73 6f 72 20 2a 70 43 73 72 2c 20 0a 20 20 53 65  sor *pCsr, .  Se
d0c0: 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72 2c 0a  gmentPtr *pPtr,.
d0d0: 20 20 69 6e 74 20 69 54 6f 70 69 63 2c 0a 20 20    int iTopic,.  
d0e0: 76 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20  void *pKey, int 
d0f0: 6e 4b 65 79 2c 0a 20 20 69 6e 74 20 69 50 67 2c  nKey,.  int iPg,
d100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d110: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20          /* Page 
d120: 74 6f 20 73 65 61 72 63 68 20 2a 2f 0a 20 20 69  to search */.  i
d130: 6e 74 20 65 53 65 65 6b 2c 20 20 20 20 20 20 20  nt eSeek,       
d140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
d150: 2a 20 53 65 61 72 63 68 20 62 69 61 73 20 2d 20  * Search bias - 
d160: 73 65 65 20 61 62 6f 76 65 20 2a 2f 0a 20 20 69  see above */.  i
d170: 6e 74 20 2a 70 69 50 74 72 2c 20 20 20 20 20 20  nt *piPtr,      
d180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
d190: 2a 20 4f 55 54 3a 20 46 43 20 70 6f 69 6e 74 65  * OUT: FC pointe
d1a0: 72 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 62 53 74  r */.  int *pbSt
d1b0: 6f 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20  op              
d1c0: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53         /* OUT: S
d1d0: 74 6f 70 20 73 65 61 72 63 68 20 66 6c 61 67 20  top search flag 
d1e0: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 50 74 72  */.){.  int iPtr
d1f0: 20 3d 20 69 50 67 3b 0a 20 20 69 6e 74 20 72 63   = iPg;.  int rc
d200: 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20 20 69 66   = LSM_OK;..  if
d210: 28 20 70 50 74 72 2d 3e 70 53 65 67 2d 3e 69 52  ( pPtr->pSeg->iR
d220: 6f 6f 74 20 29 7b 0a 20 20 20 20 50 61 67 65 20  oot ){.    Page 
d230: 2a 70 50 67 3b 0a 20 20 20 20 61 73 73 65 72 74  *pPg;.    assert
d240: 28 20 70 50 74 72 2d 3e 70 53 65 67 2d 3e 69 52  ( pPtr->pSeg->iR
d250: 6f 6f 74 21 3d 30 20 29 3b 0a 20 20 20 20 72 63  oot!=0 );.    rc
d260: 20 3d 20 73 65 65 6b 49 6e 42 74 72 65 65 28 70   = seekInBtree(p
d270: 43 73 72 2c 20 70 50 74 72 2d 3e 70 53 65 67 2c  Csr, pPtr->pSeg,
d280: 20 69 54 6f 70 69 63 2c 20 70 4b 65 79 2c 20 6e   iTopic, pKey, n
d290: 4b 65 79 2c 20 30 2c 20 26 70 50 67 29 3b 0a 20  Key, 0, &pPg);. 
d2a0: 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
d2b0: 4b 20 29 20 73 65 67 6d 65 6e 74 50 74 72 53 65  K ) segmentPtrSe
d2c0: 74 50 61 67 65 28 70 50 74 72 2c 20 70 50 67 29  tPage(pPtr, pPg)
d2d0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  ;.  }else{.    i
d2e0: 66 28 20 69 50 74 72 3d 3d 30 20 29 7b 0a 20 20  f( iPtr==0 ){.  
d2f0: 20 20 20 20 69 50 74 72 20 3d 20 70 50 74 72 2d      iPtr = pPtr-
d300: 3e 70 53 65 67 2d 3e 69 46 69 72 73 74 3b 0a 20  >pSeg->iFirst;. 
d310: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d     }.    if( rc=
d320: 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  =LSM_OK ){.     
d330: 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74 72   rc = segmentPtr
d340: 4c 6f 61 64 50 61 67 65 28 70 43 73 72 2d 3e 70  LoadPage(pCsr->p
d350: 44 62 2d 3e 70 46 53 2c 20 70 50 74 72 2c 20 69  Db->pFS, pPtr, i
d360: 50 74 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  Ptr);.    }.  }.
d370: 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f  .  if( rc==LSM_O
d380: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 65  K ){.    rc = se
d390: 67 6d 65 6e 74 50 74 72 53 65 65 6b 28 70 43 73  gmentPtrSeek(pCs
d3a0: 72 2c 20 70 50 74 72 2c 20 69 54 6f 70 69 63 2c  r, pPtr, iTopic,
d3b0: 20 70 4b 65 79 2c 20 6e 4b 65 79 2c 20 65 53 65   pKey, nKey, eSe
d3c0: 65 6b 2c 20 70 69 50 74 72 2c 20 70 62 53 74 6f  ek, piPtr, pbSto
d3d0: 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  p);.  }.  return
d3e0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65   rc;.}../*.** Se
d3f0: 65 6b 20 65 61 63 68 20 73 65 67 6d 65 6e 74 20  ek each segment 
d400: 70 6f 69 6e 74 65 72 20 69 6e 20 74 68 65 20 61  pointer in the a
d410: 72 72 61 79 20 6f 66 20 28 70 4c 76 6c 2d 3e 6e  rray of (pLvl->n
d420: 52 69 67 68 74 2b 31 29 20 61 74 20 61 50 74 72  Right+1) at aPtr
d430: 5b 5d 2e 0a 2a 2a 0a 2a 2a 20 70 62 53 74 6f 70  []..**.** pbStop
d440: 3a 0a 2a 2a 20 20 20 54 68 69 73 20 70 61 72 61  :.**   This para
d450: 6d 65 74 65 72 20 69 73 20 6f 6e 6c 79 20 73 69  meter is only si
d460: 67 6e 69 66 69 63 61 6e 74 20 69 66 20 70 61 72  gnificant if par
d470: 61 6d 65 74 65 72 20 65 53 65 65 6b 20 69 73 20  ameter eSeek is 
d480: 73 65 74 20 74 6f 0a 2a 2a 20 20 20 4c 53 4d 5f  set to.**   LSM_
d490: 53 45 45 4b 5f 45 51 2e 20 49 6e 20 74 68 69 73  SEEK_EQ. In this
d4a0: 20 63 61 73 65 2c 20 69 74 20 69 73 20 73 65 74   case, it is set
d4b0: 20 74 6f 20 74 72 75 65 20 62 65 66 6f 72 65 20   to true before 
d4c0: 72 65 74 75 72 6e 69 6e 67 20 69 66 0a 2a 2a 20  returning if.** 
d4d0: 20 20 74 68 65 20 73 65 65 6b 20 6f 70 65 72 61    the seek opera
d4e0: 74 69 6f 6e 20 69 73 20 66 69 6e 69 73 68 65 64  tion is finished
d4f0: 2e 20 54 68 69 73 20 63 61 6e 20 68 61 70 70 65  . This can happe
d500: 6e 20 69 6e 20 74 77 6f 20 77 61 79 73 3a 0a 2a  n in two ways:.*
d510: 2a 20 20 20 0a 2a 2a 20 20 20 20 20 61 29 20 41  *   .**     a) A
d520: 20 6b 65 79 20 6d 61 74 63 68 69 6e 67 20 28 70   key matching (p
d530: 4b 65 79 2f 6e 4b 65 79 29 20 69 73 20 66 6f 75  Key/nKey) is fou
d540: 6e 64 2c 20 6f 72 0a 2a 2a 20 20 20 20 20 62 29  nd, or.**     b)
d550: 20 41 20 70 6f 69 6e 74 2d 64 65 6c 65 74 65 20   A point-delete 
d560: 6f 72 20 72 61 6e 67 65 2d 64 65 6c 65 74 65 20  or range-delete 
d570: 64 65 6c 65 74 69 6e 67 20 74 68 65 20 6b 65 79  deleting the key
d580: 20 69 73 20 66 6f 75 6e 64 2e 0a 2a 2a 0a 2a 2a   is found..**.**
d590: 20 20 20 49 6e 20 63 61 73 65 20 28 61 29 2c 20     In case (a), 
d5a0: 74 68 65 20 6d 75 6c 74 69 2d 63 75 72 73 6f 72  the multi-cursor
d5b0: 20 43 55 52 53 4f 52 5f 53 45 45 4b 5f 45 51 20   CURSOR_SEEK_EQ 
d5c0: 66 6c 61 67 20 69 73 20 73 65 74 20 61 6e 64 20  flag is set and 
d5d0: 74 68 65 20 70 43 73 72 2d 3e 6b 65 79 0a 2a 2a  the pCsr->key.**
d5e0: 20 20 20 61 6e 64 20 70 43 73 72 2d 3e 76 61 6c     and pCsr->val
d5f0: 20 62 6c 6f 62 73 20 70 6f 70 75 6c 61 74 65 64   blobs populated
d600: 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
d610: 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  g..*/.static int
d620: 20 73 65 65 6b 49 6e 4c 65 76 65 6c 28 0a 20 20   seekInLevel(.  
d630: 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73  MultiCursor *pCs
d640: 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r,              
d650: 2f 2a 20 53 6f 72 74 65 64 20 63 75 72 73 6f 72  /* Sorted cursor
d660: 20 6f 62 6a 65 63 74 20 74 6f 20 73 65 65 6b 20   object to seek 
d670: 2a 2f 0a 20 20 53 65 67 6d 65 6e 74 50 74 72 20  */.  SegmentPtr 
d680: 2a 61 50 74 72 2c 20 20 20 20 20 20 20 20 20 20  *aPtr,          
d690: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
d6a0: 74 6f 20 61 72 72 61 79 20 6f 66 20 28 6e 52 68  to array of (nRh
d6b0: 73 2b 31 29 20 53 50 73 20 2a 2f 0a 20 20 69 6e  s+1) SPs */.  in
d6c0: 74 20 65 53 65 65 6b 2c 20 20 20 20 20 20 20 20  t eSeek,        
d6d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d6e0: 20 53 65 61 72 63 68 20 62 69 61 73 20 2d 20 73   Search bias - s
d6f0: 65 65 20 61 62 6f 76 65 20 2a 2f 0a 20 20 69 6e  ee above */.  in
d700: 74 20 69 54 6f 70 69 63 2c 20 20 20 20 20 20 20  t iTopic,       
d710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d720: 20 4b 65 79 20 74 6f 70 69 63 20 74 6f 20 73 65   Key topic to se
d730: 61 72 63 68 20 66 6f 72 20 2a 2f 0a 20 20 76 6f  arch for */.  vo
d740: 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b  id *pKey, int nK
d750: 65 79 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ey,           /*
d760: 20 4b 65 79 20 74 6f 20 73 65 61 72 63 68 20 66   Key to search f
d770: 6f 72 20 2a 2f 0a 20 20 50 67 6e 6f 20 2a 70 69  or */.  Pgno *pi
d780: 50 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 20  Pgno,           
d790: 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55          /* IN/OU
d7a0: 54 3a 20 66 72 61 63 74 69 6f 6e 20 63 61 73 63  T: fraction casc
d7b0: 61 64 65 20 70 6f 69 6e 74 65 72 20 28 6f 72 20  ade pointer (or 
d7c0: 30 29 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 62 53  0) */.  int *pbS
d7d0: 74 6f 70 20 20 20 20 20 20 20 20 20 20 20 20 20  top             
d7e0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
d7f0: 53 65 65 20 61 62 6f 76 65 20 2a 2f 0a 29 7b 0a  See above */.){.
d800: 20 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 20 3d 20    Level *pLvl = 
d810: 61 50 74 72 5b 30 5d 2e 70 4c 65 76 65 6c 3b 20  aPtr[0].pLevel; 
d820: 20 20 2f 2a 20 4c 65 76 65 6c 20 74 6f 20 73 65    /* Level to se
d830: 65 6b 20 77 69 74 68 69 6e 20 2a 2f 0a 20 20 69  ek within */.  i
d840: 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20  nt rc = LSM_OK; 
d850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
d860: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
d870: 0a 20 20 69 6e 74 20 69 4f 75 74 20 3d 20 30 3b  .  int iOut = 0;
d880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d890: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
d8a0: 20 72 65 74 75 72 6e 20 74 6f 20 63 61 6c 6c 65   return to calle
d8b0: 72 20 2a 2f 0a 20 20 69 6e 74 20 72 65 73 20 3d  r */.  int res =
d8c0: 20 2d 31 3b 20 20 20 20 20 20 20 20 20 20 20 20   -1;            
d8d0: 20 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74         /* Result
d8e0: 20 6f 66 20 78 43 6d 70 28 70 4b 65 79 2c 20 73   of xCmp(pKey, s
d8f0: 70 6c 69 74 29 20 2a 2f 0a 20 20 69 6e 74 20 6e  plit) */.  int n
d900: 52 68 73 20 3d 20 70 4c 76 6c 2d 3e 6e 52 69 67  Rhs = pLvl->nRig
d910: 68 74 3b 20 20 20 20 20 20 20 20 2f 2a 20 4e 75  ht;        /* Nu
d920: 6d 62 65 72 20 6f 66 20 72 69 67 68 74 2d 68 61  mber of right-ha
d930: 6e 64 2d 73 69 64 65 20 73 65 67 6d 65 6e 74 73  nd-side segments
d940: 20 2a 2f 0a 20 20 69 6e 74 20 62 53 74 6f 70 20   */.  int bStop 
d950: 3d 20 30 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68  = 0;..  /* If th
d960: 69 73 20 69 73 20 61 20 63 6f 6d 70 6f 73 69 74  is is a composit
d970: 65 20 6c 65 76 65 6c 20 28 6f 6e 65 20 63 75 72  e level (one cur
d980: 72 65 6e 74 6c 79 20 75 6e 64 65 72 67 6f 69 6e  rently undergoin
d990: 67 20 61 6e 20 69 6e 63 72 65 6d 65 6e 74 61 6c  g an incremental
d9a0: 0a 20 20 2a 2a 20 6d 65 72 67 65 29 2c 20 66 69  .  ** merge), fi
d9b0: 67 75 72 65 20 6f 75 74 20 69 66 20 74 68 65 20  gure out if the 
d9c0: 73 65 61 72 63 68 20 6b 65 79 20 69 73 20 6c 61  search key is la
d9d0: 72 67 65 72 20 6f 72 20 73 6d 61 6c 6c 65 72 20  rger or smaller 
d9e0: 74 68 61 6e 20 74 68 65 0a 20 20 2a 2a 20 6c 65  than the.  ** le
d9f0: 76 65 6c 73 20 73 70 6c 69 74 2d 6b 65 79 2e 20  vels split-key. 
da00: 20 2a 2f 0a 20 20 69 66 28 20 6e 52 68 73 20 29   */.  if( nRhs )
da10: 7b 0a 20 20 20 20 72 65 73 20 3d 20 73 6f 72 74  {.    res = sort
da20: 65 64 4b 65 79 43 6f 6d 70 61 72 65 28 70 43 73  edKeyCompare(pCs
da30: 72 2d 3e 70 44 62 2d 3e 78 43 6d 70 2c 20 69 54  r->pDb->xCmp, iT
da40: 6f 70 69 63 2c 20 70 4b 65 79 2c 20 6e 4b 65 79  opic, pKey, nKey
da50: 2c 20 0a 20 20 20 20 20 20 20 20 70 4c 76 6c 2d  , .        pLvl-
da60: 3e 69 53 70 6c 69 74 54 6f 70 69 63 2c 20 70 4c  >iSplitTopic, pL
da70: 76 6c 2d 3e 70 53 70 6c 69 74 4b 65 79 2c 20 70  vl->pSplitKey, p
da80: 4c 76 6c 2d 3e 6e 53 70 6c 69 74 4b 65 79 0a 20  Lvl->nSplitKey. 
da90: 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20     );.  }..  /* 
daa0: 49 66 20 28 72 65 73 3c 30 29 2c 20 74 68 65 6e  If (res<0), then
dab0: 20 6b 65 79 20 70 4b 65 79 2f 6e 4b 65 79 20 69   key pKey/nKey i
dac0: 73 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74  s smaller than t
dad0: 68 65 20 73 70 6c 69 74 2d 6b 65 79 20 28 6f 72  he split-key (or
dae0: 20 74 68 69 73 0a 20 20 2a 2a 20 69 73 20 6e 6f   this.  ** is no
daf0: 74 20 61 20 63 6f 6d 70 6f 73 69 74 65 20 6c 65  t a composite le
db00: 76 65 6c 20 61 6e 64 20 74 68 65 72 65 20 69 73  vel and there is
db10: 20 6e 6f 20 73 70 6c 69 74 2d 6b 65 79 29 2e 20   no split-key). 
db20: 53 65 61 72 63 68 20 74 68 65 20 0a 20 20 2a 2a  Search the .  **
db30: 20 6c 65 66 74 2d 68 61 6e 64 2d 73 69 64 65 20   left-hand-side 
db40: 6f 66 20 74 68 65 20 6c 65 76 65 6c 20 69 6e 20  of the level in 
db50: 74 68 69 73 20 63 61 73 65 2e 20 20 2a 2f 0a 20  this case.  */. 
db60: 20 69 66 28 20 72 65 73 3c 30 20 29 7b 0a 20 20   if( res<0 ){.  
db70: 20 20 69 6e 74 20 69 50 74 72 20 3d 20 30 3b 0a    int iPtr = 0;.
db80: 20 20 20 20 69 66 28 20 6e 52 68 73 3d 3d 30 20      if( nRhs==0 
db90: 29 20 69 50 74 72 20 3d 20 2a 70 69 50 67 6e 6f  ) iPtr = *piPgno
dba0: 3b 0a 0a 20 20 20 20 72 63 20 3d 20 73 65 65 6b  ;..    rc = seek
dbb0: 49 6e 53 65 67 6d 65 6e 74 28 0a 20 20 20 20 20  InSegment(.     
dbc0: 20 20 20 70 43 73 72 2c 20 26 61 50 74 72 5b 30     pCsr, &aPtr[0
dbd0: 5d 2c 20 69 54 6f 70 69 63 2c 20 70 4b 65 79 2c  ], iTopic, pKey,
dbe0: 20 6e 4b 65 79 2c 20 69 50 74 72 2c 20 65 53 65   nKey, iPtr, eSe
dbf0: 65 6b 2c 20 26 69 4f 75 74 2c 20 26 62 53 74 6f  ek, &iOut, &bSto
dc00: 70 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28  p.    );.    if(
dc10: 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 6e   rc==LSM_OK && n
dc20: 52 68 73 3e 30 20 26 26 20 65 53 65 65 6b 3d 3d  Rhs>0 && eSeek==
dc30: 4c 53 4d 5f 53 45 45 4b 5f 47 45 20 26 26 20 61  LSM_SEEK_GE && a
dc40: 50 74 72 5b 30 5d 2e 70 50 67 3d 3d 30 20 29 7b  Ptr[0].pPg==0 ){
dc50: 0a 20 20 20 20 20 20 72 65 73 20 3d 20 30 3b 0a  .      res = 0;.
dc60: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 69      }.  }.  .  i
dc70: 66 28 20 72 65 73 3e 3d 30 20 29 7b 0a 20 20 20  f( res>=0 ){.   
dc80: 20 69 6e 74 20 62 48 69 74 20 3d 20 30 3b 20 20   int bHit = 0;  
dc90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
dca0: 2a 20 54 72 75 65 20 69 66 20 61 74 20 6c 65 61  * True if at lea
dcb0: 73 74 20 6f 6e 65 20 72 68 73 20 69 73 20 6e 6f  st one rhs is no
dcc0: 74 20 45 4f 46 20 2a 2f 0a 20 20 20 20 69 6e 74  t EOF */.    int
dcd0: 20 69 50 74 72 20 3d 20 2a 70 69 50 67 6e 6f 3b   iPtr = *piPgno;
dce0: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
dcf0: 66 6f 72 28 69 3d 31 3b 20 72 63 3d 3d 4c 53 4d  for(i=1; rc==LSM
dd00: 5f 4f 4b 20 26 26 20 69 3c 3d 6e 52 68 73 20 26  _OK && i<=nRhs &
dd10: 26 20 62 53 74 6f 70 3d 3d 30 3b 20 69 2b 2b 29  & bStop==0; i++)
dd20: 7b 0a 20 20 20 20 20 20 53 65 67 6d 65 6e 74 50  {.      SegmentP
dd30: 74 72 20 2a 70 50 74 72 20 3d 20 26 61 50 74 72  tr *pPtr = &aPtr
dd40: 5b 69 5d 3b 0a 20 20 20 20 20 20 69 4f 75 74 20  [i];.      iOut 
dd50: 3d 20 30 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  = 0;.      rc = 
dd60: 73 65 65 6b 49 6e 53 65 67 6d 65 6e 74 28 0a 20  seekInSegment(. 
dd70: 20 20 20 20 20 20 20 20 20 70 43 73 72 2c 20 70           pCsr, p
dd80: 50 74 72 2c 20 69 54 6f 70 69 63 2c 20 70 4b 65  Ptr, iTopic, pKe
dd90: 79 2c 20 6e 4b 65 79 2c 20 69 50 74 72 2c 20 65  y, nKey, iPtr, e
dda0: 53 65 65 6b 2c 20 26 69 4f 75 74 2c 20 26 62 53  Seek, &iOut, &bS
ddb0: 74 6f 70 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  top.      );.   
ddc0: 20 20 20 69 50 74 72 20 3d 20 69 4f 75 74 3b 0a     iPtr = iOut;.
ddd0: 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65  .      /* If the
dde0: 20 73 65 67 6d 65 6e 74 2d 70 6f 69 6e 74 65 72   segment-pointer
ddf0: 20 68 61 73 20 73 65 74 74 6c 65 64 20 6f 6e 20   has settled on 
de00: 61 20 6b 65 79 20 74 68 61 74 20 69 73 20 73 6d  a key that is sm
de10: 61 6c 6c 65 72 20 74 68 61 6e 0a 20 20 20 20 20  aller than.     
de20: 20 2a 2a 20 74 68 65 20 73 70 6c 69 74 6b 65 79   ** the splitkey
de30: 2c 20 69 6e 76 61 6c 69 64 61 74 65 20 74 68 65  , invalidate the
de40: 20 73 65 67 6d 65 6e 74 2d 70 6f 69 6e 74 65 72   segment-pointer
de50: 2e 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20  .  */.      if( 
de60: 70 50 74 72 2d 3e 70 50 67 20 29 7b 0a 20 20 20  pPtr->pPg ){.   
de70: 20 20 20 20 20 72 65 73 20 3d 20 73 6f 72 74 65       res = sorte
de80: 64 4b 65 79 43 6f 6d 70 61 72 65 28 70 43 73 72  dKeyCompare(pCsr
de90: 2d 3e 70 44 62 2d 3e 78 43 6d 70 2c 20 0a 20 20  ->pDb->xCmp, .  
dea0: 20 20 20 20 20 20 20 20 20 20 72 74 54 6f 70 69            rtTopi
deb0: 63 28 70 50 74 72 2d 3e 65 54 79 70 65 29 2c 20  c(pPtr->eType), 
dec0: 70 50 74 72 2d 3e 70 4b 65 79 2c 20 70 50 74 72  pPtr->pKey, pPtr
ded0: 2d 3e 6e 4b 65 79 2c 20 0a 20 20 20 20 20 20 20  ->nKey, .       
dee0: 20 20 20 20 20 70 4c 76 6c 2d 3e 69 53 70 6c 69       pLvl->iSpli
def0: 74 54 6f 70 69 63 2c 20 70 4c 76 6c 2d 3e 70 53  tTopic, pLvl->pS
df00: 70 6c 69 74 4b 65 79 2c 20 70 4c 76 6c 2d 3e 6e  plitKey, pLvl->n
df10: 53 70 6c 69 74 4b 65 79 0a 20 20 20 20 20 20 20  SplitKey.       
df20: 20 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20   );.        if( 
df30: 72 65 73 3c 30 20 29 7b 0a 20 20 20 20 20 20 20  res<0 ){.       
df40: 20 20 20 69 66 28 20 70 50 74 72 2d 3e 65 54 79     if( pPtr->eTy
df50: 70 65 20 26 20 4c 53 4d 5f 53 54 41 52 54 5f 44  pe & LSM_START_D
df60: 45 4c 45 54 45 20 29 7b 0a 20 20 20 20 20 20 20  ELETE ){.       
df70: 20 20 20 20 20 70 50 74 72 2d 3e 65 54 79 70 65       pPtr->eType
df80: 20 26 3d 20 7e 4c 53 4d 5f 49 4e 53 45 52 54 3b   &= ~LSM_INSERT;
df90: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 50 74  .            pPt
dfa0: 72 2d 3e 70 4b 65 79 20 3d 20 70 4c 76 6c 2d 3e  r->pKey = pLvl->
dfb0: 70 53 70 6c 69 74 4b 65 79 3b 0a 20 20 20 20 20  pSplitKey;.     
dfc0: 20 20 20 20 20 20 20 70 50 74 72 2d 3e 6e 4b 65         pPtr->nKe
dfd0: 79 20 3d 20 70 4c 76 6c 2d 3e 6e 53 70 6c 69 74  y = pLvl->nSplit
dfe0: 4b 65 79 3b 0a 20 20 20 20 20 20 20 20 20 20 20  Key;.           
dff0: 20 70 50 74 72 2d 3e 70 56 61 6c 20 3d 20 30 3b   pPtr->pVal = 0;
e000: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 50 74  .            pPt
e010: 72 2d 3e 6e 56 61 6c 20 3d 20 30 3b 0a 20 20 20  r->nVal = 0;.   
e020: 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20         }else{.  
e030: 20 20 20 20 20 20 20 20 20 20 73 65 67 6d 65 6e            segmen
e040: 74 50 74 72 52 65 73 65 74 28 70 50 74 72 2c 20  tPtrReset(pPtr, 
e050: 4c 53 4d 5f 53 45 47 4d 45 4e 54 50 54 52 5f 46  LSM_SEGMENTPTR_F
e060: 52 45 45 5f 54 48 52 45 53 48 4f 4c 44 29 3b 0a  REE_THRESHOLD);.
e070: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
e080: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20      }.      }.. 
e090: 20 20 20 20 20 69 66 28 20 61 50 74 72 5b 69 5d       if( aPtr[i]
e0a0: 2e 70 4b 65 79 20 29 20 62 48 69 74 20 3d 20 31  .pKey ) bHit = 1
e0b0: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  ;.    }..    if(
e0c0: 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 65   rc==LSM_OK && e
e0d0: 53 65 65 6b 3d 3d 4c 53 4d 5f 53 45 45 4b 5f 4c  Seek==LSM_SEEK_L
e0e0: 45 20 26 26 20 62 48 69 74 3d 3d 30 20 29 7b 0a  E && bHit==0 ){.
e0f0: 20 20 20 20 20 20 72 63 20 3d 20 73 65 67 6d 65        rc = segme
e100: 6e 74 50 74 72 45 6e 64 28 70 43 73 72 2c 20 26  ntPtrEnd(pCsr, &
e110: 61 50 74 72 5b 30 5d 2c 20 31 29 3b 0a 20 20 20  aPtr[0], 1);.   
e120: 20 7d 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74   }.  }..  assert
e130: 28 20 65 53 65 65 6b 3d 3d 4c 53 4d 5f 53 45 45  ( eSeek==LSM_SEE
e140: 4b 5f 45 51 20 7c 7c 20 62 53 74 6f 70 3d 3d 30  K_EQ || bStop==0
e150: 20 29 3b 0a 20 20 2a 70 69 50 67 6e 6f 20 3d 20   );.  *piPgno = 
e160: 69 4f 75 74 3b 0a 20 20 2a 70 62 53 74 6f 70 20  iOut;.  *pbStop 
e170: 3d 20 62 53 74 6f 70 3b 0a 20 20 72 65 74 75 72  = bStop;.  retur
e180: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
e190: 76 6f 69 64 20 6d 75 6c 74 69 43 75 72 73 6f 72  void multiCursor
e1a0: 47 65 74 4b 65 79 28 0a 20 20 4d 75 6c 74 69 43  GetKey(.  MultiC
e1b0: 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 0a 20 20  ursor *pCsr, .  
e1c0: 69 6e 74 20 69 4b 65 79 2c 0a 20 20 69 6e 74 20  int iKey,.  int 
e1d0: 2a 70 65 54 79 70 65 2c 20 20 20 20 20 20 20 20  *peType,        
e1e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
e1f0: 55 54 3a 20 4b 65 79 20 74 79 70 65 20 28 53 4f  UT: Key type (SO
e200: 52 54 45 44 5f 57 52 49 54 45 20 65 74 63 2e 29  RTED_WRITE etc.)
e210: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a 70 70 4b   */.  void **ppK
e220: 65 79 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ey,             
e230: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50 6f        /* OUT: Po
e240: 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65 72 20  inter to buffer 
e250: 63 6f 6e 74 61 69 6e 69 6e 67 20 6b 65 79 20 2a  containing key *
e260: 2f 0a 20 20 69 6e 74 20 2a 70 6e 4b 65 79 20 20  /.  int *pnKey  
e270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e280: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 69 7a 65      /* OUT: Size
e290: 20 6f 66 20 2a 70 70 4b 65 79 20 69 6e 20 62 79   of *ppKey in by
e2a0: 74 65 73 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  tes */.){.  int 
e2b0: 6e 4b 65 79 20 3d 20 30 3b 0a 20 20 76 6f 69 64  nKey = 0;.  void
e2c0: 20 2a 70 4b 65 79 20 3d 20 30 3b 0a 20 20 69 6e   *pKey = 0;.  in
e2d0: 74 20 65 54 79 70 65 20 3d 20 30 3b 0a 0a 20 20  t eType = 0;..  
e2e0: 73 77 69 74 63 68 28 20 69 4b 65 79 20 29 7b 0a  switch( iKey ){.
e2f0: 20 20 20 20 63 61 73 65 20 43 55 52 53 4f 52 5f      case CURSOR_
e300: 44 41 54 41 5f 54 52 45 45 30 3a 0a 20 20 20 20  DATA_TREE0:.    
e310: 63 61 73 65 20 43 55 52 53 4f 52 5f 44 41 54 41  case CURSOR_DATA
e320: 5f 54 52 45 45 31 3a 20 7b 0a 20 20 20 20 20 20  _TREE1: {.      
e330: 54 72 65 65 43 75 72 73 6f 72 20 2a 70 54 72 65  TreeCursor *pTre
e340: 65 43 73 72 20 3d 20 70 43 73 72 2d 3e 61 70 54  eCsr = pCsr->apT
e350: 72 65 65 43 73 72 5b 69 4b 65 79 2d 43 55 52 53  reeCsr[iKey-CURS
e360: 4f 52 5f 44 41 54 41 5f 54 52 45 45 30 5d 3b 0a  OR_DATA_TREE0];.
e370: 20 20 20 20 20 20 69 66 28 20 6c 73 6d 54 72 65        if( lsmTre
e380: 65 43 75 72 73 6f 72 56 61 6c 69 64 28 70 54 72  eCursorValid(pTr
e390: 65 65 43 73 72 29 20 29 7b 0a 20 20 20 20 20 20  eeCsr) ){.      
e3a0: 20 20 6c 73 6d 54 72 65 65 43 75 72 73 6f 72 4b    lsmTreeCursorK
e3b0: 65 79 28 70 54 72 65 65 43 73 72 2c 20 26 65 54  ey(pTreeCsr, &eT
e3c0: 79 70 65 2c 20 26 70 4b 65 79 2c 20 26 6e 4b 65  ype, &pKey, &nKe
e3d0: 79 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  y);.      }.    
e3e0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a    break;.    }..
e3f0: 20 20 20 20 63 61 73 65 20 43 55 52 53 4f 52 5f      case CURSOR_
e400: 44 41 54 41 5f 53 59 53 54 45 4d 3a 20 7b 0a 20  DATA_SYSTEM: {. 
e410: 20 20 20 20 20 53 6e 61 70 73 68 6f 74 20 2a 70       Snapshot *p
e420: 57 6f 72 6b 65 72 20 3d 20 70 43 73 72 2d 3e 70  Worker = pCsr->p
e430: 44 62 2d 3e 70 57 6f 72 6b 65 72 3b 0a 20 20 20  Db->pWorker;.   
e440: 20 20 20 69 66 28 20 70 57 6f 72 6b 65 72 20 26     if( pWorker &
e450: 26 20 28 70 43 73 72 2d 3e 66 6c 61 67 73 20 26  & (pCsr->flags &
e460: 20 43 55 52 53 4f 52 5f 46 4c 55 53 48 5f 46 52   CURSOR_FLUSH_FR
e470: 45 45 4c 49 53 54 29 20 29 7b 0a 20 20 20 20 20  EELIST) ){.     
e480: 20 20 20 69 6e 74 20 6e 45 6e 74 72 79 20 3d 20     int nEntry = 
e490: 70 57 6f 72 6b 65 72 2d 3e 66 72 65 65 6c 69 73  pWorker->freelis
e4a0: 74 2e 6e 45 6e 74 72 79 3b 0a 20 20 20 20 20 20  t.nEntry;.      
e4b0: 20 20 69 66 28 20 70 43 73 72 2d 3e 69 46 72 65    if( pCsr->iFre
e4c0: 65 20 3c 20 28 6e 45 6e 74 72 79 2a 32 29 20 29  e < (nEntry*2) )
e4d0: 7b 0a 20 20 20 20 20 20 20 20 20 20 46 72 65 65  {.          Free
e4e0: 6c 69 73 74 45 6e 74 72 79 20 2a 61 45 6e 74 72  listEntry *aEntr
e4f0: 79 20 3d 20 70 57 6f 72 6b 65 72 2d 3e 66 72 65  y = pWorker->fre
e500: 65 6c 69 73 74 2e 61 45 6e 74 72 79 3b 0a 20 20  elist.aEntry;.  
e510: 20 20 20 20 20 20 20 20 69 6e 74 20 69 20 3d 20          int i = 
e520: 6e 45 6e 74 72 79 20 2d 20 31 20 2d 20 28 70 43  nEntry - 1 - (pC
e530: 73 72 2d 3e 69 46 72 65 65 20 2f 20 32 29 3b 0a  sr->iFree / 2);.
e540: 20 20 20 20 20 20 20 20 20 20 75 33 32 20 69 4b            u32 iK
e550: 65 79 20 3d 20 30 3b 0a 0a 20 20 20 20 20 20 20  ey = 0;..       
e560: 20 20 20 69 66 28 20 28 70 43 73 72 2d 3e 69 46     if( (pCsr->iF
e570: 72 65 65 20 25 20 32 29 20 29 7b 0a 20 20 20 20  ree % 2) ){.    
e580: 20 20 20 20 20 20 20 20 65 54 79 70 65 20 3d 20          eType = 
e590: 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45 54 45 7c 4c  LSM_END_DELETE|L
e5a0: 53 4d 5f 53 59 53 54 45 4d 4b 45 59 3b 0a 20 20  SM_SYSTEMKEY;.  
e5b0: 20 20 20 20 20 20 20 20 20 20 69 4b 65 79 20 3d            iKey =
e5c0: 20 61 45 6e 74 72 79 5b 69 5d 2e 69 42 6c 6b 2d   aEntry[i].iBlk-
e5d0: 31 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c  1;.          }el
e5e0: 73 65 20 69 66 28 20 61 45 6e 74 72 79 5b 69 5d  se if( aEntry[i]
e5f0: 2e 69 49 64 3e 3d 30 20 29 7b 0a 20 20 20 20 20  .iId>=0 ){.     
e600: 20 20 20 20 20 20 20 65 54 79 70 65 20 3d 20 4c         eType = L
e610: 53 4d 5f 49 4e 53 45 52 54 7c 4c 53 4d 5f 53 59  SM_INSERT|LSM_SY
e620: 53 54 45 4d 4b 45 59 3b 0a 20 20 20 20 20 20 20  STEMKEY;.       
e630: 20 20 20 20 20 69 4b 65 79 20 3d 20 61 45 6e 74       iKey = aEnt
e640: 72 79 5b 69 5d 2e 69 42 6c 6b 3b 0a 0a 20 20 20  ry[i].iBlk;..   
e650: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74           /* If t
e660: 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 65 6e 74  he in-memory ent
e670: 72 79 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 62  ry immediately b
e680: 65 66 6f 72 65 20 74 68 69 73 20 6f 6e 65 20 77  efore this one w
e690: 61 73 20 61 0a 20 20 20 20 20 20 20 20 20 20 20  as a.           
e6a0: 20 20 2a 2a 20 44 45 4c 45 54 45 2c 20 61 6e 64    ** DELETE, and
e6b0: 20 74 68 65 20 62 6c 6f 63 6b 20 6e 75 6d 62 65   the block numbe
e6c0: 72 20 69 73 20 6f 6e 65 20 67 72 65 61 74 65 72  r is one greater
e6d0: 20 74 68 61 6e 20 74 68 65 20 63 75 72 72 65 6e   than the curren
e6e0: 74 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 2a  t.             *
e6f0: 2a 20 62 6c 6f 63 6b 20 6e 75 6d 62 65 72 2c 20  * block number, 
e700: 6d 61 72 6b 20 74 68 69 73 20 65 6e 74 72 79 20  mark this entry 
e710: 61 73 20 61 6e 20 22 65 6e 64 2d 64 65 6c 65 74  as an "end-delet
e720: 65 2d 72 61 6e 67 65 22 2e 20 2a 2f 0a 20 20 20  e-range". */.   
e730: 20 20 20 20 20 20 20 20 20 69 66 28 20 69 3c 28           if( i<(
e740: 6e 45 6e 74 72 79 2d 31 29 20 26 26 20 61 45 6e  nEntry-1) && aEn
e750: 74 72 79 5b 69 2b 31 5d 2e 69 42 6c 6b 3d 3d 69  try[i+1].iBlk==i
e760: 4b 65 79 2b 31 20 26 26 20 61 45 6e 74 72 79 5b  Key+1 && aEntry[
e770: 69 2b 31 5d 2e 69 49 64 3c 30 20 29 7b 0a 20 20  i+1].iId<0 ){.  
e780: 20 20 20 20 20 20 20 20 20 20 20 20 65 54 79 70              eTyp
e790: 65 20 7c 3d 20 4c 53 4d 5f 45 4e 44 5f 44 45 4c  e |= LSM_END_DEL
e7a0: 45 54 45 3b 0a 20 20 20 20 20 20 20 20 20 20 20  ETE;.           
e7b0: 20 7d 0a 0a 20 20 20 20 20 20 20 20 20 20 7d 65   }..          }e
e7c0: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20  lse{.           
e7d0: 20 65 54 79 70 65 20 3d 20 4c 53 4d 5f 53 54 41   eType = LSM_STA
e7e0: 52 54 5f 44 45 4c 45 54 45 7c 4c 53 4d 5f 53 59  RT_DELETE|LSM_SY
e7f0: 53 54 45 4d 4b 45 59 3b 0a 20 20 20 20 20 20 20  STEMKEY;.       
e800: 20 20 20 20 20 69 4b 65 79 20 3d 20 61 45 6e 74       iKey = aEnt
e810: 72 79 5b 69 5d 2e 69 42 6c 6b 20 2b 20 31 3b 0a  ry[i].iBlk + 1;.
e820: 20 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20            }..   
e830: 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65         /* If the
e840: 20 69 6e 2d 6d 65 6d 6f 72 79 20 65 6e 74 72 79   in-memory entry
e850: 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 61 66 74   immediately aft
e860: 65 72 20 74 68 69 73 20 6f 6e 65 20 69 73 20 61  er this one is a
e870: 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 44 45  .          ** DE
e880: 4c 45 54 45 2c 20 61 6e 64 20 74 68 65 20 62 6c  LETE, and the bl
e890: 6f 63 6b 20 6e 75 6d 62 65 72 20 69 73 20 6f 6e  ock number is on
e8a0: 65 20 6c 65 73 73 20 74 68 61 6e 20 74 68 65 20  e less than the 
e8b0: 63 75 72 72 65 6e 74 0a 20 20 20 20 20 20 20 20  current.        
e8c0: 20 20 2a 2a 20 6b 65 79 2c 20 6d 61 72 6b 20 74    ** key, mark t
e8d0: 68 69 73 20 65 6e 74 72 79 20 61 73 20 61 6e 20  his entry as an 
e8e0: 22 73 74 61 72 74 2d 64 65 6c 65 74 65 2d 72 61  "start-delete-ra
e8f0: 6e 67 65 22 2e 20 20 2a 2f 0a 20 20 20 20 20 20  nge".  */.      
e900: 20 20 20 20 69 66 28 20 69 3e 30 20 26 26 20 61      if( i>0 && a
e910: 45 6e 74 72 79 5b 69 2d 31 5d 2e 69 42 6c 6b 3d  Entry[i-1].iBlk=
e920: 3d 69 4b 65 79 2d 31 20 26 26 20 61 45 6e 74 72  =iKey-1 && aEntr
e930: 79 5b 69 2d 31 5d 2e 69 49 64 3c 30 20 29 7b 0a  y[i-1].iId<0 ){.
e940: 20 20 20 20 20 20 20 20 20 20 20 20 65 54 79 70              eTyp
e950: 65 20 7c 3d 20 4c 53 4d 5f 53 54 41 52 54 5f 44  e |= LSM_START_D
e960: 45 4c 45 54 45 3b 0a 20 20 20 20 20 20 20 20 20  ELETE;.         
e970: 20 7d 0a 0a 20 20 20 20 20 20 20 20 20 20 70 4b   }..          pK
e980: 65 79 20 3d 20 70 43 73 72 2d 3e 70 53 79 73 74  ey = pCsr->pSyst
e990: 65 6d 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 20  emVal;.         
e9a0: 20 6e 4b 65 79 20 3d 20 34 3b 0a 20 20 20 20 20   nKey = 4;.     
e9b0: 20 20 20 20 20 6c 73 6d 50 75 74 55 33 32 28 70       lsmPutU32(p
e9c0: 4b 65 79 2c 20 7e 69 4b 65 79 29 3b 0a 20 20 20  Key, ~iKey);.   
e9d0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
e9e0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
e9f0: 7d 0a 0a 20 20 20 20 64 65 66 61 75 6c 74 3a 20  }..    default: 
ea00: 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 50 74 72  {.      int iPtr
ea10: 20 3d 20 69 4b 65 79 20 2d 20 43 55 52 53 4f 52   = iKey - CURSOR
ea20: 5f 44 41 54 41 5f 53 45 47 4d 45 4e 54 3b 0a 20  _DATA_SEGMENT;. 
ea30: 20 20 20 20 20 61 73 73 65 72 74 28 20 69 50 74       assert( iPt
ea40: 72 3e 3d 30 20 29 3b 0a 20 20 20 20 20 20 69 66  r>=0 );.      if
ea50: 28 20 69 50 74 72 3d 3d 70 43 73 72 2d 3e 6e 50  ( iPtr==pCsr->nP
ea60: 74 72 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  tr ){.        if
ea70: 28 20 70 43 73 72 2d 3e 70 42 74 43 73 72 20 29  ( pCsr->pBtCsr )
ea80: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 4b 65 79  {.          pKey
ea90: 20 3d 20 70 43 73 72 2d 3e 70 42 74 43 73 72 2d   = pCsr->pBtCsr-
eaa0: 3e 70 4b 65 79 3b 0a 20 20 20 20 20 20 20 20 20  >pKey;.         
eab0: 20 6e 4b 65 79 20 3d 20 70 43 73 72 2d 3e 70 42   nKey = pCsr->pB
eac0: 74 43 73 72 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20  tCsr->nKey;.    
ead0: 20 20 20 20 20 20 65 54 79 70 65 20 3d 20 70 43        eType = pC
eae0: 73 72 2d 3e 70 42 74 43 73 72 2d 3e 65 54 79 70  sr->pBtCsr->eTyp
eaf0: 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  e;.        }.   
eb00: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 69 50 74     }else if( iPt
eb10: 72 3c 70 43 73 72 2d 3e 6e 50 74 72 20 29 7b 0a  r<pCsr->nPtr ){.
eb20: 20 20 20 20 20 20 20 20 53 65 67 6d 65 6e 74 50          SegmentP
eb30: 74 72 20 2a 70 50 74 72 20 3d 20 26 70 43 73 72  tr *pPtr = &pCsr
eb40: 2d 3e 61 50 74 72 5b 69 50 74 72 5d 3b 0a 20 20  ->aPtr[iPtr];.  
eb50: 20 20 20 20 20 20 69 66 28 20 70 50 74 72 2d 3e        if( pPtr->
eb60: 70 50 67 20 29 7b 0a 20 20 20 20 20 20 20 20 20  pPg ){.         
eb70: 20 70 4b 65 79 20 3d 20 70 50 74 72 2d 3e 70 4b   pKey = pPtr->pK
eb80: 65 79 3b 0a 20 20 20 20 20 20 20 20 20 20 6e 4b  ey;.          nK
eb90: 65 79 20 3d 20 70 50 74 72 2d 3e 6e 4b 65 79 3b  ey = pPtr->nKey;
eba0: 0a 20 20 20 20 20 20 20 20 20 20 65 54 79 70 65  .          eType
ebb0: 20 3d 20 70 50 74 72 2d 3e 65 54 79 70 65 3b 0a   = pPtr->eType;.
ebc0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
ebd0: 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  }.      break;. 
ebe0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
ebf0: 70 65 54 79 70 65 20 29 20 2a 70 65 54 79 70 65  peType ) *peType
ec00: 20 3d 20 65 54 79 70 65 3b 0a 20 20 69 66 28 20   = eType;.  if( 
ec10: 70 6e 4b 65 79 20 29 20 2a 70 6e 4b 65 79 20 3d  pnKey ) *pnKey =
ec20: 20 6e 4b 65 79 3b 0a 20 20 69 66 28 20 70 70 4b   nKey;.  if( ppK
ec30: 65 79 20 29 20 2a 70 70 4b 65 79 20 3d 20 70 4b  ey ) *ppKey = pK
ec40: 65 79 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  ey;.}..static in
ec50: 74 20 73 6f 72 74 65 64 44 62 4b 65 79 43 6f 6d  t sortedDbKeyCom
ec60: 70 61 72 65 28 0a 20 20 4d 75 6c 74 69 43 75 72  pare(.  MultiCur
ec70: 73 6f 72 20 2a 70 43 73 72 2c 0a 20 20 69 6e 74  sor *pCsr,.  int
ec80: 20 69 4c 68 73 46 6c 61 67 73 2c 20 76 6f 69 64   iLhsFlags, void
ec90: 20 2a 70 4c 68 73 4b 65 79 2c 20 69 6e 74 20 6e   *pLhsKey, int n
eca0: 4c 68 73 4b 65 79 2c 0a 20 20 69 6e 74 20 69 52  LhsKey,.  int iR
ecb0: 68 73 46 6c 61 67 73 2c 20 76 6f 69 64 20 2a 70  hsFlags, void *p
ecc0: 52 68 73 4b 65 79 2c 20 69 6e 74 20 6e 52 68 73  RhsKey, int nRhs
ecd0: 4b 65 79 0a 29 7b 0a 20 20 69 6e 74 20 28 2a 78  Key.){.  int (*x
ece0: 43 6d 70 29 28 76 6f 69 64 20 2a 2c 20 69 6e 74  Cmp)(void *, int
ecf0: 2c 20 76 6f 69 64 20 2a 2c 20 69 6e 74 29 20 3d  , void *, int) =
ed00: 20 70 43 73 72 2d 3e 70 44 62 2d 3e 78 43 6d 70   pCsr->pDb->xCmp
ed10: 3b 0a 20 20 69 6e 74 20 72 65 73 3b 0a 0a 20 20  ;.  int res;..  
ed20: 2f 2a 20 43 6f 6d 70 61 72 65 20 74 68 65 20 6b  /* Compare the k
ed30: 65 79 73 2c 20 69 6e 63 6c 75 64 69 6e 67 20 74  eys, including t
ed40: 68 65 20 73 79 73 74 65 6d 20 66 6c 61 67 2e 20  he system flag. 
ed50: 2a 2f 0a 20 20 72 65 73 20 3d 20 73 6f 72 74 65  */.  res = sorte
ed60: 64 4b 65 79 43 6f 6d 70 61 72 65 28 78 43 6d 70  dKeyCompare(xCmp
ed70: 2c 20 0a 20 20 20 20 72 74 54 6f 70 69 63 28 69  , .    rtTopic(i
ed80: 4c 68 73 46 6c 61 67 73 29 2c 20 70 4c 68 73 4b  LhsFlags), pLhsK
ed90: 65 79 2c 20 6e 4c 68 73 4b 65 79 2c 0a 20 20 20  ey, nLhsKey,.   
eda0: 20 72 74 54 6f 70 69 63 28 69 52 68 73 46 6c 61   rtTopic(iRhsFla
edb0: 67 73 29 2c 20 70 52 68 73 4b 65 79 2c 20 6e 52  gs), pRhsKey, nR
edc0: 68 73 4b 65 79 0a 20 20 29 3b 0a 0a 20 20 2f 2a  hsKey.  );..  /*
edd0: 20 49 66 20 61 20 6b 65 79 20 68 61 73 20 74 68   If a key has th
ede0: 65 20 4c 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45  e LSM_START_DELE
edf0: 54 45 20 66 6c 61 67 20 73 65 74 2c 20 62 75 74  TE flag set, but
ee00: 20 6e 6f 74 20 74 68 65 20 4c 53 4d 5f 49 4e 53   not the LSM_INS
ee10: 45 52 54 20 6f 72 0a 20 20 2a 2a 20 4c 53 4d 5f  ERT or.  ** LSM_
ee20: 50 4f 49 4e 54 5f 44 45 4c 45 54 45 20 66 6c 61  POINT_DELETE fla
ee30: 67 73 2c 20 69 74 20 69 73 20 63 6f 6e 73 69 64  gs, it is consid
ee40: 65 72 65 64 20 61 20 64 65 6c 74 61 20 6c 61 72  ered a delta lar
ee50: 67 65 72 2e 20 54 68 69 73 20 70 72 65 76 65 6e  ger. This preven
ee60: 74 73 0a 20 20 2a 2a 20 74 68 65 20 62 65 67 69  ts.  ** the begi
ee70: 6e 6e 69 6e 67 20 6f 66 20 61 6e 20 6f 70 65 6e  nning of an open
ee80: 2d 65 6e 64 65 64 20 73 65 74 20 66 72 6f 6d 20  -ended set from 
ee90: 6d 61 73 6b 69 6e 67 20 61 20 64 61 74 61 62 61  masking a databa
eea0: 73 65 20 65 6e 74 72 79 20 6f 72 0a 20 20 2a 2a  se entry or.  **
eeb0: 20 64 65 6c 65 74 65 20 61 74 20 61 20 6c 6f 77   delete at a low
eec0: 65 72 20 6c 65 76 65 6c 2e 20 20 2a 2f 0a 20 20  er level.  */.  
eed0: 69 66 28 20 72 65 73 3d 3d 30 20 26 26 20 28 70  if( res==0 && (p
eee0: 43 73 72 2d 3e 66 6c 61 67 73 20 26 20 43 55 52  Csr->flags & CUR
eef0: 53 4f 52 5f 49 47 4e 4f 52 45 5f 44 45 4c 45 54  SOR_IGNORE_DELET
ef00: 45 29 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20  E) ){.    const 
ef10: 69 6e 74 20 6d 20 3d 20 4c 53 4d 5f 50 4f 49 4e  int m = LSM_POIN
ef20: 54 5f 44 45 4c 45 54 45 7c 4c 53 4d 5f 49 4e 53  T_DELETE|LSM_INS
ef30: 45 52 54 7c 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45  ERT|LSM_END_DELE
ef40: 54 45 20 7c 4c 53 4d 5f 53 54 41 52 54 5f 44 45  TE |LSM_START_DE
ef50: 4c 45 54 45 3b 0a 20 20 20 20 69 6e 74 20 69 44  LETE;.    int iD
ef60: 65 6c 31 20 3d 20 30 3b 0a 20 20 20 20 69 6e 74  el1 = 0;.    int
ef70: 20 69 44 65 6c 32 20 3d 20 30 3b 0a 0a 20 20 20   iDel2 = 0;..   
ef80: 20 69 66 28 20 4c 53 4d 5f 53 54 41 52 54 5f 44   if( LSM_START_D
ef90: 45 4c 45 54 45 3d 3d 28 69 4c 68 73 46 6c 61 67  ELETE==(iLhsFlag
efa0: 73 20 26 20 6d 29 20 29 20 69 44 65 6c 31 20 3d  s & m) ) iDel1 =
efb0: 20 2b 31 3b 0a 20 20 20 20 69 66 28 20 4c 53 4d   +1;.    if( LSM
efc0: 5f 45 4e 44 5f 44 45 4c 45 54 45 20 20 3d 3d 28  _END_DELETE  ==(
efd0: 69 4c 68 73 46 6c 61 67 73 20 26 20 6d 29 20 29  iLhsFlags & m) )
efe0: 20 69 44 65 6c 31 20 3d 20 2d 31 3b 0a 20 20 20   iDel1 = -1;.   
eff0: 20 69 66 28 20 4c 53 4d 5f 53 54 41 52 54 5f 44   if( LSM_START_D
f000: 45 4c 45 54 45 3d 3d 28 69 52 68 73 46 6c 61 67  ELETE==(iRhsFlag
f010: 73 20 26 20 6d 29 20 29 20 69 44 65 6c 32 20 3d  s & m) ) iDel2 =
f020: 20 2b 31 3b 0a 20 20 20 20 69 66 28 20 4c 53 4d   +1;.    if( LSM
f030: 5f 45 4e 44 5f 44 45 4c 45 54 45 20 20 3d 3d 28  _END_DELETE  ==(
f040: 69 52 68 73 46 6c 61 67 73 20 26 20 6d 29 20 29  iRhsFlags & m) )
f050: 20 69 44 65 6c 32 20 3d 20 2d 31 3b 0a 0a 20 20   iDel2 = -1;..  
f060: 20 20 72 65 73 20 3d 20 28 69 44 65 6c 31 20 2d    res = (iDel1 -
f070: 20 69 44 65 6c 32 29 3b 0a 20 20 7d 0a 0a 20 20   iDel2);.  }..  
f080: 72 65 74 75 72 6e 20 72 65 73 3b 0a 7d 0a 0a 73  return res;.}..s
f090: 74 61 74 69 63 20 76 6f 69 64 20 6d 75 6c 74 69  tatic void multi
f0a0: 43 75 72 73 6f 72 44 6f 43 6f 6d 70 61 72 65 28  CursorDoCompare(
f0b0: 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73  MultiCursor *pCs
f0c0: 72 2c 20 69 6e 74 20 69 4f 75 74 2c 20 69 6e 74  r, int iOut, int
f0d0: 20 62 52 65 76 65 72 73 65 29 7b 0a 20 20 69 6e   bReverse){.  in
f0e0: 74 20 69 31 3b 0a 20 20 69 6e 74 20 69 32 3b 0a  t i1;.  int i2;.
f0f0: 20 20 69 6e 74 20 69 52 65 73 3b 0a 20 20 76 6f    int iRes;.  vo
f100: 69 64 20 2a 70 4b 65 79 31 3b 20 69 6e 74 20 6e  id *pKey1; int n
f110: 4b 65 79 31 3b 20 69 6e 74 20 65 54 79 70 65 31  Key1; int eType1
f120: 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 32 3b  ;.  void *pKey2;
f130: 20 69 6e 74 20 6e 4b 65 79 32 3b 20 69 6e 74 20   int nKey2; int 
f140: 65 54 79 70 65 32 3b 0a 20 20 63 6f 6e 73 74 20  eType2;.  const 
f150: 69 6e 74 20 6d 75 6c 20 3d 20 28 62 52 65 76 65  int mul = (bReve
f160: 72 73 65 20 3f 20 2d 31 20 3a 20 31 29 3b 0a 0a  rse ? -1 : 1);..
f170: 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
f180: 61 54 72 65 65 20 26 26 20 69 4f 75 74 3c 70 43  aTree && iOut<pC
f190: 73 72 2d 3e 6e 54 72 65 65 20 29 3b 0a 20 20 69  sr->nTree );.  i
f1a0: 66 28 20 69 4f 75 74 3e 3d 28 70 43 73 72 2d 3e  f( iOut>=(pCsr->
f1b0: 6e 54 72 65 65 2f 32 29 20 29 7b 0a 20 20 20 20  nTree/2) ){.    
f1c0: 69 31 20 3d 20 28 69 4f 75 74 20 2d 20 70 43 73  i1 = (iOut - pCs
f1d0: 72 2d 3e 6e 54 72 65 65 2f 32 29 20 2a 20 32 3b  r->nTree/2) * 2;
f1e0: 0a 20 20 20 20 69 32 20 3d 20 69 31 20 2b 20 31  .    i2 = i1 + 1
f1f0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  ;.  }else{.    i
f200: 31 20 3d 20 70 43 73 72 2d 3e 61 54 72 65 65 5b  1 = pCsr->aTree[
f210: 69 4f 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20  iOut*2];.    i2 
f220: 3d 20 70 43 73 72 2d 3e 61 54 72 65 65 5b 69 4f  = pCsr->aTree[iO
f230: 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20 20  ut*2+1];.  }..  
f240: 6d 75 6c 74 69 43 75 72 73 6f 72 47 65 74 4b 65  multiCursorGetKe
f250: 79 28 70 43 73 72 2c 20 69 31 2c 20 26 65 54 79  y(pCsr, i1, &eTy
f260: 70 65 31 2c 20 26 70 4b 65 79 31 2c 20 26 6e 4b  pe1, &pKey1, &nK
f270: 65 79 31 29 3b 0a 20 20 6d 75 6c 74 69 43 75 72  ey1);.  multiCur
f280: 73 6f 72 47 65 74 4b 65 79 28 70 43 73 72 2c 20  sorGetKey(pCsr, 
f290: 69 32 2c 20 26 65 54 79 70 65 32 2c 20 26 70 4b  i2, &eType2, &pK
f2a0: 65 79 32 2c 20 26 6e 4b 65 79 32 29 3b 0a 0a 20  ey2, &nKey2);.. 
f2b0: 20 69 66 28 20 70 4b 65 79 31 3d 3d 30 20 29 7b   if( pKey1==0 ){
f2c0: 0a 20 20 20 20 69 52 65 73 20 3d 20 69 32 3b 0a  .    iRes = i2;.
f2d0: 20 20 7d 65 6c 73 65 20 69 66 28 20 70 4b 65 79    }else if( pKey
f2e0: 32 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 73  2==0 ){.    iRes
f2f0: 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a   = i1;.  }else{.
f300: 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 0a 20 20      int res;..  
f310: 20 20 2f 2a 20 43 6f 6d 70 61 72 65 20 74 68 65    /* Compare the
f320: 20 6b 65 79 73 20 2a 2f 0a 20 20 20 20 72 65 73   keys */.    res
f330: 20 3d 20 73 6f 72 74 65 64 44 62 4b 65 79 43 6f   = sortedDbKeyCo
f340: 6d 70 61 72 65 28 70 43 73 72 2c 0a 20 20 20 20  mpare(pCsr,.    
f350: 20 20 20 20 65 54 79 70 65 31 2c 20 70 4b 65 79      eType1, pKey
f360: 31 2c 20 6e 4b 65 79 31 2c 20 65 54 79 70 65 32  1, nKey1, eType2
f370: 2c 20 70 4b 65 79 32 2c 20 6e 4b 65 79 32 0a 20  , pKey2, nKey2. 
f380: 20 20 20 29 3b 0a 0a 20 20 20 20 72 65 73 20 3d     );..    res =
f390: 20 72 65 73 20 2a 20 6d 75 6c 3b 0a 20 20 20 20   res * mul;.    
f3a0: 69 66 28 20 72 65 73 3d 3d 30 20 29 7b 0a 20 20  if( res==0 ){.  
f3b0: 20 20 20 20 2f 2a 20 54 68 65 20 74 77 6f 20 6b      /* The two k
f3c0: 65 79 73 20 61 72 65 20 69 64 65 6e 74 69 63 61  eys are identica
f3d0: 6c 2e 20 4e 6f 72 6d 61 6c 6c 79 2c 20 74 68 69  l. Normally, thi
f3e0: 73 20 6d 65 61 6e 73 20 74 68 61 74 20 74 68 65  s means that the
f3f0: 20 6b 65 79 20 66 72 6f 6d 0a 20 20 20 20 20 20   key from.      
f400: 2a 2a 20 74 68 65 20 6e 65 77 65 72 20 72 75 6e  ** the newer run
f410: 20 63 6c 6f 62 62 65 72 73 20 74 68 65 20 6f 6c   clobbers the ol
f420: 64 2e 20 48 6f 77 65 76 65 72 2c 20 69 66 20 74  d. However, if t
f430: 68 65 20 6e 65 77 65 72 20 6b 65 79 20 69 73 20  he newer key is 
f440: 61 0a 20 20 20 20 20 20 2a 2a 20 73 65 70 61 72  a.      ** separ
f450: 61 74 6f 72 20 6b 65 79 2c 20 6f 72 20 61 20 72  ator key, or a r
f460: 61 6e 67 65 2d 64 65 6c 65 74 65 2d 62 6f 75 6e  ange-delete-boun
f470: 64 61 72 79 20 6f 6e 6c 79 2c 20 64 6f 20 6e 6f  dary only, do no
f480: 74 20 61 6c 6c 6f 77 20 69 74 0a 20 20 20 20 20  t allow it.     
f490: 20 2a 2a 20 74 6f 20 63 6c 6f 62 62 65 72 20 61   ** to clobber a
f4a0: 6e 20 6f 6c 64 65 72 20 65 6e 74 72 79 2e 20 20  n older entry.  
f4b0: 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 63 31  */.      int nc1
f4c0: 20 3d 20 28 65 54 79 70 65 31 20 26 20 28 4c 53   = (eType1 & (LS
f4d0: 4d 5f 49 4e 53 45 52 54 7c 4c 53 4d 5f 50 4f 49  M_INSERT|LSM_POI
f4e0: 4e 54 5f 44 45 4c 45 54 45 29 29 3d 3d 30 3b 0a  NT_DELETE))==0;.
f4f0: 20 20 20 20 20 20 69 6e 74 20 6e 63 32 20 3d 20        int nc2 = 
f500: 28 65 54 79 70 65 32 20 26 20 28 4c 53 4d 5f 49  (eType2 & (LSM_I
f510: 4e 53 45 52 54 7c 4c 53 4d 5f 50 4f 49 4e 54 5f  NSERT|LSM_POINT_
f520: 44 45 4c 45 54 45 29 29 3d 3d 30 3b 0a 20 20 20  DELETE))==0;.   
f530: 20 20 20 69 52 65 73 20 3d 20 28 6e 63 31 20 3e     iRes = (nc1 >
f540: 20 6e 63 32 29 20 3f 20 69 32 20 3a 20 69 31 3b   nc2) ? i2 : i1;
f550: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72  .    }else if( r
f560: 65 73 3c 30 20 29 7b 0a 20 20 20 20 20 20 69 52  es<0 ){.      iR
f570: 65 73 20 3d 20 69 31 3b 0a 20 20 20 20 7d 65 6c  es = i1;.    }el
f580: 73 65 7b 0a 20 20 20 20 20 20 69 52 65 73 20 3d  se{.      iRes =
f590: 20 69 32 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a   i2;.    }.  }..
f5a0: 20 20 70 43 73 72 2d 3e 61 54 72 65 65 5b 69 4f    pCsr->aTree[iO
f5b0: 75 74 5d 20 3d 20 69 52 65 73 3b 0a 7d 0a 0a 2f  ut] = iRes;.}../
f5c0: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
f5d0: 6f 6e 20 61 64 76 61 6e 63 65 73 20 73 65 67 6d  on advances segm
f5e0: 65 6e 74 20 70 6f 69 6e 74 65 72 20 69 50 74 72  ent pointer iPtr
f5f0: 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 6d 75   belonging to mu
f600: 6c 74 69 2d 63 75 72 73 6f 72 0a 2a 2a 20 70 43  lti-cursor.** pC
f610: 73 72 20 66 6f 72 77 61 72 64 20 28 62 52 65 76  sr forward (bRev
f620: 65 72 73 65 3d 3d 30 29 20 6f 72 20 62 61 63 6b  erse==0) or back
f630: 77 61 72 64 20 28 62 52 65 76 65 72 73 65 21 3d  ward (bReverse!=
f640: 30 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  0)..**.** If the
f650: 20 73 65 67 6d 65 6e 74 20 70 6f 69 6e 74 65 72   segment pointer
f660: 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 73 65 67   points to a seg
f670: 6d 65 6e 74 20 74 68 61 74 20 69 73 20 70 61 72  ment that is par
f680: 74 20 6f 66 20 61 20 63 6f 6d 70 6f 73 69 74 65  t of a composite
f690: 0a 2a 2a 20 6c 65 76 65 6c 2c 20 74 68 65 6e 20  .** level, then 
f6a0: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 70  the following sp
f6b0: 65 63 69 61 6c 20 63 61 73 65 20 69 73 20 68 61  ecial case is ha
f6c0: 6e 64 6c 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 2a  ndled..**.**   *
f6d0: 20 49 66 20 69 50 74 72 20 69 73 20 74 68 65 20   If iPtr is the 
f6e0: 6c 68 73 20 6f 66 20 61 20 63 6f 6d 70 6f 73 69  lhs of a composi
f6f0: 74 65 20 6c 65 76 65 6c 2c 20 61 6e 64 20 74 68  te level, and th
f700: 65 20 63 75 72 73 6f 72 20 69 73 20 62 65 69 6e  e cursor is bein
f710: 67 0a 2a 2a 20 20 20 20 20 61 64 76 61 6e 63 65  g.**     advance
f720: 64 20 66 6f 72 77 61 72 64 73 2c 20 61 6e 64 20  d forwards, and 
f730: 73 65 67 6d 65 6e 74 20 69 50 74 72 20 69 73 20  segment iPtr is 
f740: 61 74 20 45 4f 46 2c 20 6d 6f 76 65 20 61 6c 6c  at EOF, move all
f750: 20 70 6f 69 6e 74 65 72 73 0a 2a 2a 20 20 20 20   pointers.**    
f760: 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64   that correspond
f770: 20 74 6f 20 72 68 73 20 73 65 67 6d 65 6e 74 73   to rhs segments
f780: 20 6f 66 20 74 68 65 20 73 61 6d 65 20 6c 65 76   of the same lev
f790: 65 6c 20 74 6f 20 74 68 65 20 66 69 72 73 74 0a  el to the first.
f7a0: 2a 2a 20 20 20 20 20 6b 65 79 20 69 6e 20 74 68  **     key in th
f7b0: 65 69 72 20 72 65 73 70 65 63 74 69 76 65 20 64  eir respective d
f7c0: 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ata..*/.static i
f7d0: 6e 74 20 73 65 67 6d 65 6e 74 43 75 72 73 6f 72  nt segmentCursor
f7e0: 41 64 76 61 6e 63 65 28 0a 20 20 4d 75 6c 74 69  Advance(.  Multi
f7f0: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 0a 20  Cursor *pCsr, . 
f800: 20 69 6e 74 20 69 50 74 72 2c 0a 20 20 69 6e 74   int iPtr,.  int
f810: 20 62 52 65 76 65 72 73 65 0a 29 7b 0a 20 20 69   bReverse.){.  i
f820: 6e 74 20 72 63 3b 0a 20 20 53 65 67 6d 65 6e 74  nt rc;.  Segment
f830: 50 74 72 20 2a 70 50 74 72 20 3d 20 26 70 43 73  Ptr *pPtr = &pCs
f840: 72 2d 3e 61 50 74 72 5b 69 50 74 72 5d 3b 0a 20  r->aPtr[iPtr];. 
f850: 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 20 3d 20 70   Level *pLvl = p
f860: 50 74 72 2d 3e 70 4c 65 76 65 6c 3b 0a 20 20 69  Ptr->pLevel;.  i
f870: 6e 74 20 62 43 6f 6d 70 6f 73 69 74 65 3b 20 20  nt bComposite;  
f880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
f890: 2a 20 54 72 75 65 20 69 66 20 70 50 74 72 20 69  * True if pPtr i
f8a0: 73 20 70 61 72 74 20 6f 66 20 63 6f 6d 70 6f 73  s part of compos
f8b0: 69 74 65 20 6c 65 76 65 6c 20 2a 2f 0a 0a 20 20  ite level */..  
f8c0: 2f 2a 20 41 64 76 61 6e 63 65 20 74 68 65 20 73  /* Advance the s
f8d0: 65 67 6d 65 6e 74 2d 70 6f 69 6e 74 65 72 20 6f  egment-pointer o
f8e0: 62 6a 65 63 74 2e 20 2a 2f 0a 20 20 72 63 20 3d  bject. */.  rc =
f8f0: 20 73 65 67 6d 65 6e 74 50 74 72 41 64 76 61 6e   segmentPtrAdvan
f900: 63 65 28 70 43 73 72 2c 20 70 50 74 72 2c 20 62  ce(pCsr, pPtr, b
f910: 52 65 76 65 72 73 65 29 3b 0a 20 20 69 66 28 20  Reverse);.  if( 
f920: 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65 74  rc!=LSM_OK ) ret
f930: 75 72 6e 20 72 63 3b 0a 0a 20 20 62 43 6f 6d 70  urn rc;..  bComp
f940: 6f 73 69 74 65 20 3d 20 28 70 4c 76 6c 2d 3e 6e  osite = (pLvl->n
f950: 52 69 67 68 74 3e 30 20 26 26 20 70 43 73 72 2d  Right>0 && pCsr-
f960: 3e 6e 50 74 72 3e 70 4c 76 6c 2d 3e 6e 52 69 67  >nPtr>pLvl->nRig
f970: 68 74 29 3b 0a 20 20 69 66 28 20 62 43 6f 6d 70  ht);.  if( bComp
f980: 6f 73 69 74 65 20 26 26 20 70 50 74 72 2d 3e 70  osite && pPtr->p
f990: 50 67 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74  Pg==0 ){.    int
f9a0: 20 62 46 69 78 20 3d 20 30 3b 0a 20 20 20 20 69   bFix = 0;.    i
f9b0: 66 28 20 28 62 52 65 76 65 72 73 65 3d 3d 30 29  f( (bReverse==0)
f9c0: 3d 3d 28 70 50 74 72 2d 3e 70 53 65 67 3d 3d 26  ==(pPtr->pSeg==&
f9d0: 70 4c 76 6c 2d 3e 6c 68 73 29 20 29 7b 0a 20 20  pLvl->lhs) ){.  
f9e0: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20      int i;.     
f9f0: 20 69 66 28 20 62 52 65 76 65 72 73 65 20 29 7b   if( bReverse ){
fa00: 0a 20 20 20 20 20 20 20 20 53 65 67 6d 65 6e 74  .        Segment
fa10: 50 74 72 20 2a 70 4c 68 73 20 3d 20 26 70 43 73  Ptr *pLhs = &pCs
fa20: 72 2d 3e 61 50 74 72 5b 69 50 74 72 20 2d 20 31  r->aPtr[iPtr - 1
fa30: 20 2d 20 28 70 50 74 72 2d 3e 70 53 65 67 20 2d   - (pPtr->pSeg -
fa40: 20 70 4c 76 6c 2d 3e 61 52 68 73 29 5d 3b 0a 20   pLvl->aRhs)];. 
fa50: 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20         for(i=0; 
fa60: 69 3c 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 3b 20  i<pLvl->nRight; 
fa70: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20  i++){.          
fa80: 69 66 28 20 70 4c 68 73 5b 69 2b 31 5d 2e 70 50  if( pLhs[i+1].pP
fa90: 67 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  g ) break;.     
faa0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 28     }.        if(
fab0: 20 69 3d 3d 70 4c 76 6c 2d 3e 6e 52 69 67 68 74   i==pLvl->nRight
fac0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 62 46   ){.          bF
fad0: 69 78 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  ix = 1;.        
fae0: 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74    rc = segmentPt
faf0: 72 45 6e 64 28 70 43 73 72 2c 20 70 4c 68 73 2c  rEnd(pCsr, pLhs,
fb00: 20 31 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20   1);.        }. 
fb10: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
fb20: 20 20 20 20 62 46 69 78 20 3d 20 31 3b 0a 20 20      bFix = 1;.  
fb30: 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 72        for(i=0; r
fb40: 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 69 3c 70  c==LSM_OK && i<p
fb50: 4c 76 6c 2d 3e 6e 52 69 67 68 74 3b 20 69 2b 2b  Lvl->nRight; i++
fb60: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ){.          rc 
fb70: 3d 20 73 6f 72 74 65 64 52 68 73 46 69 72 73 74  = sortedRhsFirst
fb80: 28 70 43 73 72 2c 20 70 4c 76 6c 2c 20 26 70 43  (pCsr, pLvl, &pC
fb90: 73 72 2d 3e 61 50 74 72 5b 69 50 74 72 2b 31 2b  sr->aPtr[iPtr+1+
fba0: 69 5d 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  i]);.        }. 
fbb0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
fbc0: 20 20 69 66 28 20 62 46 69 78 20 29 7b 0a 20 20    if( bFix ){.  
fbd0: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20      int i;.     
fbe0: 20 66 6f 72 28 69 3d 70 43 73 72 2d 3e 6e 54 72   for(i=pCsr->nTr
fbf0: 65 65 2d 31 3b 20 69 3e 30 3b 20 69 2d 2d 29 7b  ee-1; i>0; i--){
fc00: 0a 20 20 20 20 20 20 20 20 6d 75 6c 74 69 43 75  .        multiCu
fc10: 72 73 6f 72 44 6f 43 6f 6d 70 61 72 65 28 70 43  rsorDoCompare(pC
fc20: 73 72 2c 20 69 2c 20 62 52 65 76 65 72 73 65 29  sr, i, bReverse)
fc30: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
fc40: 20 20 7d 0a 0a 23 69 66 20 30 0a 20 20 69 66 28    }..#if 0.  if(
fc50: 20 62 43 6f 6d 70 6f 73 69 74 65 20 26 26 20 70   bComposite && p
fc60: 50 74 72 2d 3e 70 53 65 67 3d 3d 26 70 4c 76 6c  Ptr->pSeg==&pLvl
fc70: 2d 3e 6c 68 73 20 20 20 20 20 20 20 2f 2a 20 6c  ->lhs       /* l
fc80: 68 73 20 6f 66 20 63 6f 6d 70 6f 73 69 74 65 20  hs of composite 
fc90: 6c 65 76 65 6c 20 2a 2f 0a 20 20 20 26 26 20 62  level */.   && b
fca0: 52 65 76 65 72 73 65 3d 3d 30 20 20 20 20 20 20  Reverse==0      
fcb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fcc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 63 73 72            /* csr
fcd0: 20 61 64 76 61 6e 63 65 64 20 66 6f 72 77 61 72   advanced forwar
fce0: 64 73 20 2a 2f 0a 20 20 20 26 26 20 70 50 74 72  ds */.   && pPtr
fcf0: 2d 3e 70 50 67 3d 3d 30 20 20 20 20 20 20 20 20  ->pPg==0        
fd00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fd10: 20 20 20 20 20 20 20 2f 2a 20 73 65 67 6d 65 6e         /* segmen
fd20: 74 20 61 74 20 45 4f 46 20 2a 2f 0a 20 20 29 7b  t at EOF */.  ){
fd30: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
fd40: 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 4c 53 4d  for(i=0; rc==LSM
fd50: 5f 4f 4b 20 26 26 20 69 3c 70 4c 76 6c 2d 3e 6e  _OK && i<pLvl->n
fd60: 52 69 67 68 74 3b 20 69 2b 2b 29 7b 0a 20 20 20  Right; i++){.   
fd70: 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64 52 68     rc = sortedRh
fd80: 73 46 69 72 73 74 28 70 43 73 72 2c 20 70 4c 76  sFirst(pCsr, pLv
fd90: 6c 2c 20 26 70 43 73 72 2d 3e 61 50 74 72 5b 69  l, &pCsr->aPtr[i
fda0: 50 74 72 2b 31 2b 69 5d 29 3b 0a 20 20 20 20 7d  Ptr+1+i]);.    }
fdb0: 0a 20 20 20 20 66 6f 72 28 69 3d 70 43 73 72 2d  .    for(i=pCsr-
fdc0: 3e 6e 54 72 65 65 2d 31 3b 20 69 3e 30 3b 20 69  >nTree-1; i>0; i
fdd0: 2d 2d 29 7b 0a 20 20 20 20 20 20 6d 75 6c 74 69  --){.      multi
fde0: 43 75 72 73 6f 72 44 6f 43 6f 6d 70 61 72 65 28  CursorDoCompare(
fdf0: 70 43 73 72 2c 20 69 2c 20 30 29 3b 0a 20 20 20  pCsr, i, 0);.   
fe00: 20 7d 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20   }.  }.#endif.. 
fe10: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
fe20: 74 61 74 69 63 20 76 6f 69 64 20 6d 63 75 72 73  tatic void mcurs
fe30: 6f 72 46 72 65 65 43 6f 6d 70 6f 6e 65 6e 74 73  orFreeComponents
fe40: 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43  (MultiCursor *pC
fe50: 73 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  sr){.  int i;.  
fe60: 6c 73 6d 5f 65 6e 76 20 2a 70 45 6e 76 20 3d 20  lsm_env *pEnv = 
fe70: 70 43 73 72 2d 3e 70 44 62 2d 3e 70 45 6e 76 3b  pCsr->pDb->pEnv;
fe80: 0a 0a 20 20 2f 2a 20 43 6c 6f 73 65 20 74 68 65  ..  /* Close the
fe90: 20 74 72 65 65 20 63 75 72 73 6f 72 2c 20 69 66   tree cursor, if
fea0: 20 61 6e 79 2e 20 2a 2f 0a 20 20 6c 73 6d 54 72   any. */.  lsmTr
feb0: 65 65 43 75 72 73 6f 72 44 65 73 74 72 6f 79 28  eeCursorDestroy(
fec0: 70 43 73 72 2d 3e 61 70 54 72 65 65 43 73 72 5b  pCsr->apTreeCsr[
fed0: 30 5d 29 3b 0a 20 20 6c 73 6d 54 72 65 65 43 75  0]);.  lsmTreeCu
fee0: 72 73 6f 72 44 65 73 74 72 6f 79 28 70 43 73 72  rsorDestroy(pCsr
fef0: 2d 3e 61 70 54 72 65 65 43 73 72 5b 31 5d 29 3b  ->apTreeCsr[1]);
ff00: 0a 0a 20 20 2f 2a 20 52 65 73 65 74 20 74 68 65  ..  /* Reset the
ff10: 20 73 65 67 6d 65 6e 74 20 70 6f 69 6e 74 65 72   segment pointer
ff20: 73 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  s */.  for(i=0; 
ff30: 69 3c 70 43 73 72 2d 3e 6e 50 74 72 3b 20 69 2b  i<pCsr->nPtr; i+
ff40: 2b 29 7b 0a 20 20 20 20 73 65 67 6d 65 6e 74 50  +){.    segmentP
ff50: 74 72 52 65 73 65 74 28 26 70 43 73 72 2d 3e 61  trReset(&pCsr->a
ff60: 50 74 72 5b 69 5d 2c 20 30 29 3b 0a 20 20 7d 0a  Ptr[i], 0);.  }.
ff70: 0a 20 20 2f 2a 20 41 6e 64 20 74 68 65 20 62 2d  .  /* And the b-
ff80: 74 72 65 65 20 63 75 72 73 6f 72 2c 20 69 66 20  tree cursor, if 
ff90: 61 6e 79 20 2a 2f 0a 20 20 62 74 72 65 65 43 75  any */.  btreeCu
ffa0: 72 73 6f 72 46 72 65 65 28 70 43 73 72 2d 3e 70  rsorFree(pCsr->p
ffb0: 42 74 43 73 72 29 3b 0a 0a 20 20 2f 2a 20 46 72  BtCsr);..  /* Fr
ffc0: 65 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 2a  ee allocations *
ffd0: 2f 0a 20 20 6c 73 6d 46 72 65 65 28 70 45 6e 76  /.  lsmFree(pEnv
ffe0: 2c 20 70 43 73 72 2d 3e 61 50 74 72 29 3b 0a 20  , pCsr->aPtr);. 
fff0: 20 6c 73 6d 46 72 65 65 28 70 45 6e 76 2c 20 70   lsmFree(pEnv, p
10000 43 73 72 2d 3e 61 54 72 65 65 29 3b 0a 20 20 6c  Csr->aTree);.  l
10010 73 6d 46 72 65 65 28 70 45 6e 76 2c 20 70 43 73  smFree(pEnv, pCs
10020 72 2d 3e 70 53 79 73 74 65 6d 56 61 6c 29 3b 0a  r->pSystemVal);.
10030 0a 20 20 2f 2a 20 5a 65 72 6f 20 66 69 65 6c 64  .  /* Zero field
10040 73 20 2a 2f 0a 20 20 70 43 73 72 2d 3e 6e 50 74  s */.  pCsr->nPt
10050 72 20 3d 20 30 3b 0a 20 20 70 43 73 72 2d 3e 61  r = 0;.  pCsr->a
10060 50 74 72 20 3d 20 30 3b 0a 20 20 70 43 73 72 2d  Ptr = 0;.  pCsr-
10070 3e 6e 54 72 65 65 20 3d 20 30 3b 0a 20 20 70 43  >nTree = 0;.  pC
10080 73 72 2d 3e 61 54 72 65 65 20 3d 20 30 3b 0a 20  sr->aTree = 0;. 
10090 20 70 43 73 72 2d 3e 70 53 79 73 74 65 6d 56 61   pCsr->pSystemVa
100a0 6c 20 3d 20 30 3b 0a 20 20 70 43 73 72 2d 3e 61  l = 0;.  pCsr->a
100b0 70 54 72 65 65 43 73 72 5b 30 5d 20 3d 20 30 3b  pTreeCsr[0] = 0;
100c0 0a 20 20 70 43 73 72 2d 3e 61 70 54 72 65 65 43  .  pCsr->apTreeC
100d0 73 72 5b 31 5d 20 3d 20 30 3b 0a 20 20 70 43 73  sr[1] = 0;.  pCs
100e0 72 2d 3e 70 42 74 43 73 72 20 3d 20 30 3b 0a 7d  r->pBtCsr = 0;.}
100f0 0a 0a 76 6f 69 64 20 6c 73 6d 4d 43 75 72 73 6f  ..void lsmMCurso
10100 72 46 72 65 65 43 61 63 68 65 28 6c 73 6d 5f 64  rFreeCache(lsm_d
10110 62 20 2a 70 44 62 29 7b 0a 20 20 4d 75 6c 74 69  b *pDb){.  Multi
10120 43 75 72 73 6f 72 20 2a 70 3b 0a 20 20 4d 75 6c  Cursor *p;.  Mul
10130 74 69 43 75 72 73 6f 72 20 2a 70 4e 65 78 74 3b  tiCursor *pNext;
10140 0a 20 20 66 6f 72 28 70 3d 70 44 62 2d 3e 70 43  .  for(p=pDb->pC
10150 73 72 43 61 63 68 65 3b 20 70 3b 20 70 3d 70 4e  srCache; p; p=pN
10160 65 78 74 29 7b 0a 20 20 20 20 70 4e 65 78 74 20  ext){.    pNext 
10170 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  = p->pNext;.    
10180 6c 73 6d 4d 43 75 72 73 6f 72 43 6c 6f 73 65 28  lsmMCursorClose(
10190 70 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 70 44 62  p, 0);.  }.  pDb
101a0 2d 3e 70 43 73 72 43 61 63 68 65 20 3d 20 30 3b  ->pCsrCache = 0;
101b0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20  .}../*.** Close 
101c0 74 68 65 20 63 75 72 73 6f 72 20 70 61 73 73 65  the cursor passe
101d0 64 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61  d as the first a
101e0 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 49  rgument..**.** I
101f0 66 20 74 68 65 20 62 43 61 63 68 65 20 70 61 72  f the bCache par
10200 61 6d 65 74 65 72 20 69 73 20 74 72 75 65 2c 20  ameter is true, 
10210 74 68 65 6e 20 73 68 69 66 74 20 74 68 65 20 63  then shift the c
10220 75 72 73 6f 72 20 74 6f 20 74 68 65 20 70 43 73  ursor to the pCs
10230 72 43 61 63 68 65 0a 2a 2a 20 6c 69 73 74 20 66  rCache.** list f
10240 6f 72 20 70 6f 73 73 69 62 6c 65 20 72 65 75 73  or possible reus
10250 65 20 69 6e 73 74 65 61 64 20 6f 66 20 61 63 74  e instead of act
10260 75 61 6c 6c 79 20 64 65 6c 65 74 69 6e 67 20 69  ually deleting i
10270 74 2e 0a 2a 2f 0a 76 6f 69 64 20 6c 73 6d 4d 43  t..*/.void lsmMC
10280 75 72 73 6f 72 43 6c 6f 73 65 28 4d 75 6c 74 69  ursorClose(Multi
10290 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e  Cursor *pCsr, in
102a0 74 20 62 43 61 63 68 65 29 7b 0a 20 20 69 66 28  t bCache){.  if(
102b0 20 70 43 73 72 20 29 7b 0a 20 20 20 20 6c 73 6d   pCsr ){.    lsm
102c0 5f 64 62 20 2a 70 44 62 20 3d 20 70 43 73 72 2d  _db *pDb = pCsr-
102d0 3e 70 44 62 3b 0a 20 20 20 20 4d 75 6c 74 69 43  >pDb;.    MultiC
102e0 75 72 73 6f 72 20 2a 2a 70 70 3b 20 20 20 20 20  ursor **pp;     
102f0 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61          /* Itera
10300 74 6f 72 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a  tor variable */.
10310 0a 20 20 20 20 2f 2a 20 54 68 65 20 63 75 72 73  .    /* The curs
10320 6f 72 20 6d 61 79 20 6f 72 20 6d 61 79 20 6e 6f  or may or may no
10330 74 20 62 65 20 63 75 72 72 65 6e 74 6c 79 20 70  t be currently p
10340 61 72 74 20 6f 66 20 74 68 65 20 6c 69 6e 6b 65  art of the linke
10350 64 20 6c 69 73 74 20 0a 20 20 20 20 2a 2a 20 73  d list .    ** s
10360 74 61 72 74 69 6e 67 20 61 74 20 6c 73 6d 5f 64  tarting at lsm_d
10370 62 2e 70 43 73 72 2e 20 49 66 20 69 74 20 69 73  b.pCsr. If it is
10380 2c 20 65 78 74 72 61 63 74 20 69 74 2e 20 20 2a  , extract it.  *
10390 2f 0a 20 20 20 20 66 6f 72 28 70 70 3d 26 70 44  /.    for(pp=&pD
103a0 62 2d 3e 70 43 73 72 3b 20 2a 70 70 3b 20 70 70  b->pCsr; *pp; pp
103b0 3d 26 28 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29  =&((*pp)->pNext)
103c0 29 7b 0a 20 20 20 20 20 20 69 66 28 20 2a 70 70  ){.      if( *pp
103d0 3d 3d 70 43 73 72 20 29 7b 0a 20 20 20 20 20 20  ==pCsr ){.      
103e0 20 20 2a 70 70 20 3d 20 70 43 73 72 2d 3e 70 4e    *pp = pCsr->pN
103f0 65 78 74 3b 0a 20 20 20 20 20 20 20 20 62 72 65  ext;.        bre
10400 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
10410 7d 0a 0a 20 20 20 20 69 66 28 20 62 43 61 63 68  }..    if( bCach
10420 65 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69  e ){.      int i
10430 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
10440 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
10450 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
10460 68 20 73 65 67 6d 65 6e 74 2d 70 6f 69 6e 74 65  h segment-pointe
10470 72 73 20 2a 2f 0a 0a 20 20 20 20 20 20 2f 2a 20  rs */..      /* 
10480 52 65 6c 65 61 73 65 20 61 6e 79 20 70 61 67 65  Release any page
10490 20 72 65 66 65 72 65 6e 63 65 73 20 68 65 6c 64   references held
104a0 20 62 79 20 74 68 69 73 20 63 75 72 73 6f 72 2e   by this cursor.
104b0 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74   */.      assert
104c0 28 20 21 70 43 73 72 2d 3e 70 42 74 43 73 72 20  ( !pCsr->pBtCsr 
104d0 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30  );.      for(i=0
104e0 3b 20 69 3c 70 43 73 72 2d 3e 6e 50 74 72 3b 20  ; i<pCsr->nPtr; 
104f0 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 53 65  i++){.        Se
10500 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72 20 3d  gmentPtr *pPtr =
10510 20 26 70 43 73 72 2d 3e 61 50 74 72 5b 69 5d 3b   &pCsr->aPtr[i];
10520 0a 20 20 20 20 20 20 20 20 6c 73 6d 46 73 50 61  .        lsmFsPa
10530 67 65 52 65 6c 65 61 73 65 28 70 50 74 72 2d 3e  geRelease(pPtr->
10540 70 50 67 29 3b 0a 20 20 20 20 20 20 20 20 70 50  pPg);.        pP
10550 74 72 2d 3e 70 50 67 20 3d 20 30 3b 0a 20 20 20  tr->pPg = 0;.   
10560 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 52     }..      /* R
10570 65 73 65 74 20 74 68 65 20 74 72 65 65 20 63 75  eset the tree cu
10580 72 73 6f 72 73 20 2a 2f 0a 20 20 20 20 20 20 6c  rsors */.      l
10590 73 6d 54 72 65 65 43 75 72 73 6f 72 52 65 73 65  smTreeCursorRese
105a0 74 28 70 43 73 72 2d 3e 61 70 54 72 65 65 43 73  t(pCsr->apTreeCs
105b0 72 5b 30 5d 29 3b 0a 20 20 20 20 20 20 6c 73 6d  r[0]);.      lsm
105c0 54 72 65 65 43 75 72 73 6f 72 52 65 73 65 74 28  TreeCursorReset(
105d0 70 43 73 72 2d 3e 61 70 54 72 65 65 43 73 72 5b  pCsr->apTreeCsr[
105e0 31 5d 29 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 41  1]);..      /* A
105f0 64 64 20 74 68 65 20 63 75 72 73 6f 72 20 74 6f  dd the cursor to
10600 20 74 68 65 20 70 43 73 72 43 61 63 68 65 20 6c   the pCsrCache l
10610 69 73 74 20 2a 2f 0a 20 20 20 20 20 20 70 43 73  ist */.      pCs
10620 72 2d 3e 70 4e 65 78 74 20 3d 20 70 44 62 2d 3e  r->pNext = pDb->
10630 70 43 73 72 43 61 63 68 65 3b 0a 20 20 20 20 20  pCsrCache;.     
10640 20 70 44 62 2d 3e 70 43 73 72 43 61 63 68 65 20   pDb->pCsrCache 
10650 3d 20 70 43 73 72 3b 0a 20 20 20 20 7d 65 6c 73  = pCsr;.    }els
10660 65 7b 0a 20 20 20 20 20 20 2f 2a 20 46 72 65 65  e{.      /* Free
10670 20 74 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20   the allocation 
10680 75 73 65 64 20 74 6f 20 63 61 63 68 65 20 74 68  used to cache th
10690 65 20 63 75 72 72 65 6e 74 20 6b 65 79 2c 20 69  e current key, i
106a0 66 20 61 6e 79 2e 20 2a 2f 0a 20 20 20 20 20 20  f any. */.      
106b0 73 6f 72 74 65 64 42 6c 6f 62 46 72 65 65 28 26  sortedBlobFree(&
106c0 70 43 73 72 2d 3e 6b 65 79 29 3b 0a 20 20 20 20  pCsr->key);.    
106d0 20 20 73 6f 72 74 65 64 42 6c 6f 62 46 72 65 65    sortedBlobFree
106e0 28 26 70 43 73 72 2d 3e 76 61 6c 29 3b 0a 0a 20  (&pCsr->val);.. 
106f0 20 20 20 20 20 2f 2a 20 46 72 65 65 20 74 68 65       /* Free the
10700 20 63 6f 6d 70 6f 6e 65 6e 74 20 63 75 72 73 6f   component curso
10710 72 73 20 2a 2f 0a 20 20 20 20 20 20 6d 63 75 72  rs */.      mcur
10720 73 6f 72 46 72 65 65 43 6f 6d 70 6f 6e 65 6e 74  sorFreeComponent
10730 73 28 70 43 73 72 29 3b 0a 0a 20 20 20 20 20 20  s(pCsr);..      
10740 2f 2a 20 46 72 65 65 20 74 68 65 20 63 75 72 73  /* Free the curs
10750 6f 72 20 73 74 72 75 63 74 75 72 65 20 69 74 73  or structure its
10760 65 6c 66 20 2a 2f 0a 20 20 20 20 20 20 6c 73 6d  elf */.      lsm
10770 46 72 65 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20  Free(pDb->pEnv, 
10780 70 43 73 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  pCsr);.    }.  }
10790 0a 7d 0a 0a 23 64 65 66 69 6e 65 20 54 52 45 45  .}..#define TREE
107a0 5f 4e 4f 4e 45 20 30 0a 23 64 65 66 69 6e 65 20  _NONE 0.#define 
107b0 54 52 45 45 5f 4f 4c 44 20 20 31 0a 23 64 65 66  TREE_OLD  1.#def
107c0 69 6e 65 20 54 52 45 45 5f 42 4f 54 48 20 32 0a  ine TREE_BOTH 2.
107d0 0a 2f 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72  ./*.** Parameter
107e0 20 65 54 72 65 65 20 69 73 20 6f 6e 65 20 6f 66   eTree is one of
107f0 20 54 52 45 45 5f 4f 4c 44 20 6f 72 20 54 52 45   TREE_OLD or TRE
10800 45 5f 42 4f 54 48 2e 0a 2a 2f 0a 73 74 61 74 69  E_BOTH..*/.stati
10810 63 20 69 6e 74 20 6d 75 6c 74 69 43 75 72 73 6f  c int multiCurso
10820 72 41 64 64 54 72 65 65 28 4d 75 6c 74 69 43 75  rAddTree(MultiCu
10830 72 73 6f 72 20 2a 70 43 73 72 2c 20 53 6e 61 70  rsor *pCsr, Snap
10840 73 68 6f 74 20 2a 70 53 6e 61 70 2c 20 69 6e 74  shot *pSnap, int
10850 20 65 54 72 65 65 29 7b 0a 20 20 69 6e 74 20 72   eTree){.  int r
10860 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 6c 73  c = LSM_OK;.  ls
10870 6d 5f 64 62 20 2a 64 62 20 3d 20 70 43 73 72 2d  m_db *db = pCsr-
10880 3e 70 44 62 3b 0a 0a 20 20 2f 2a 20 41 64 64 20  >pDb;..  /* Add 
10890 61 20 74 72 65 65 20 63 75 72 73 6f 72 20 6f 6e  a tree cursor on
108a0 20 74 68 65 20 27 6f 6c 64 27 20 74 72 65 65 2c   the 'old' tree,
108b0 20 69 66 20 69 74 20 65 78 69 73 74 73 2e 20 2a   if it exists. *
108c0 2f 0a 20 20 69 66 28 20 65 54 72 65 65 21 3d 54  /.  if( eTree!=T
108d0 52 45 45 5f 4e 4f 4e 45 20 0a 20 20 20 26 26 20  REE_NONE .   && 
108e0 6c 73 6d 54 72 65 65 48 61 73 4f 6c 64 28 64 62  lsmTreeHasOld(db
108f0 29 20 0a 20 20 20 26 26 20 64 62 2d 3e 74 72 65  ) .   && db->tre
10900 65 68 64 72 2e 69 4f 6c 64 4c 6f 67 21 3d 70 53  ehdr.iOldLog!=pS
10910 6e 61 70 2d 3e 69 4c 6f 67 4f 66 66 20 0a 20 20  nap->iLogOff .  
10920 29 7b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 54  ){.    rc = lsmT
10930 72 65 65 43 75 72 73 6f 72 4e 65 77 28 64 62 2c  reeCursorNew(db,
10940 20 31 2c 20 26 70 43 73 72 2d 3e 61 70 54 72 65   1, &pCsr->apTre
10950 65 43 73 72 5b 31 5d 29 3b 0a 20 20 7d 0a 0a 20  eCsr[1]);.  }.. 
10960 20 2f 2a 20 41 64 64 20 61 20 74 72 65 65 20 63   /* Add a tree c
10970 75 72 73 6f 72 20 6f 6e 20 74 68 65 20 27 63 75  ursor on the 'cu
10980 72 72 65 6e 74 27 20 74 72 65 65 2c 20 69 66 20  rrent' tree, if 
10990 72 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20 20 69  required. */.  i
109a0 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26  f( rc==LSM_OK &&
109b0 20 65 54 72 65 65 3d 3d 54 52 45 45 5f 42 4f 54   eTree==TREE_BOT
109c0 48 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 6c 73  H ){.    rc = ls
109d0 6d 54 72 65 65 43 75 72 73 6f 72 4e 65 77 28 64  mTreeCursorNew(d
109e0 62 2c 20 30 2c 20 26 70 43 73 72 2d 3e 61 70 54  b, 0, &pCsr->apT
109f0 72 65 65 43 73 72 5b 30 5d 29 3b 0a 20 20 7d 0a  reeCsr[0]);.  }.
10a00 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
10a10 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74  .static int mult
10a20 69 43 75 72 73 6f 72 41 64 64 52 68 73 28 4d 75  iCursorAddRhs(Mu
10a30 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  ltiCursor *pCsr,
10a40 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 29 7b 0a 20   Level *pLvl){. 
10a50 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 6e 52   int i;.  int nR
10a60 68 73 20 3d 20 70 4c 76 6c 2d 3e 6e 52 69 67 68  hs = pLvl->nRigh
10a70 74 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 4c  t;..  assert( pL
10a80 76 6c 2d 3e 6e 52 69 67 68 74 3e 30 20 29 3b 0a  vl->nRight>0 );.
10a90 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
10aa0 61 50 74 72 3d 3d 30 20 29 3b 0a 20 20 70 43 73  aPtr==0 );.  pCs
10ab0 72 2d 3e 61 50 74 72 20 3d 20 6c 73 6d 4d 61 6c  r->aPtr = lsmMal
10ac0 6c 6f 63 5a 65 72 6f 28 70 43 73 72 2d 3e 70 44  locZero(pCsr->pD
10ad0 62 2d 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66 28  b->pEnv, sizeof(
10ae0 53 65 67 6d 65 6e 74 50 74 72 29 20 2a 20 6e 52  SegmentPtr) * nR
10af0 68 73 29 3b 0a 20 20 69 66 28 20 21 70 43 73 72  hs);.  if( !pCsr
10b00 2d 3e 61 50 74 72 20 29 20 72 65 74 75 72 6e 20  ->aPtr ) return 
10b10 4c 53 4d 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a  LSM_NOMEM_BKPT;.
10b20 20 20 70 43 73 72 2d 3e 6e 50 74 72 20 3d 20 6e    pCsr->nPtr = n
10b30 52 68 73 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b  Rhs;..  for(i=0;
10b40 20 69 3c 6e 52 68 73 3b 20 69 2b 2b 29 7b 0a 20   i<nRhs; i++){. 
10b50 20 20 20 70 43 73 72 2d 3e 61 50 74 72 5b 69 5d     pCsr->aPtr[i]
10b60 2e 70 53 65 67 20 3d 20 26 70 4c 76 6c 2d 3e 61  .pSeg = &pLvl->a
10b70 52 68 73 5b 69 5d 3b 0a 20 20 20 20 70 43 73 72  Rhs[i];.    pCsr
10b80 2d 3e 61 50 74 72 5b 69 5d 2e 70 4c 65 76 65 6c  ->aPtr[i].pLevel
10b90 20 3d 20 70 4c 76 6c 3b 0a 20 20 7d 0a 0a 20 20   = pLvl;.  }..  
10ba0 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 7d  return LSM_OK;.}
10bb0 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 75  ..static void mu
10bc0 6c 74 69 43 75 72 73 6f 72 41 64 64 4f 6e 65 28  ltiCursorAddOne(
10bd0 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73  MultiCursor *pCs
10be0 72 2c 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 2c 20  r, Level *pLvl, 
10bf0 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 69 66 28  int *pRc){.  if(
10c00 20 2a 70 52 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b   *pRc==LSM_OK ){
10c10 0a 20 20 20 20 69 6e 74 20 69 50 74 72 20 3d 20  .    int iPtr = 
10c20 70 43 73 72 2d 3e 6e 50 74 72 3b 0a 20 20 20 20  pCsr->nPtr;.    
10c30 69 6e 74 20 69 3b 0a 20 20 20 20 70 43 73 72 2d  int i;.    pCsr-
10c40 3e 61 50 74 72 5b 69 50 74 72 5d 2e 70 4c 65 76  >aPtr[iPtr].pLev
10c50 65 6c 20 3d 20 70 4c 76 6c 3b 0a 20 20 20 20 70  el = pLvl;.    p
10c60 43 73 72 2d 3e 61 50 74 72 5b 69 50 74 72 5d 2e  Csr->aPtr[iPtr].
10c70 70 53 65 67 20 3d 20 26 70 4c 76 6c 2d 3e 6c 68  pSeg = &pLvl->lh
10c80 73 3b 0a 20 20 20 20 69 50 74 72 2b 2b 3b 0a 20  s;.    iPtr++;. 
10c90 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 4c     for(i=0; i<pL
10ca0 76 6c 2d 3e 6e 52 69 67 68 74 3b 20 69 2b 2b 29  vl->nRight; i++)
10cb0 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 61 50  {.      pCsr->aP
10cc0 74 72 5b 69 50 74 72 5d 2e 70 4c 65 76 65 6c 20  tr[iPtr].pLevel 
10cd0 3d 20 70 4c 76 6c 3b 0a 20 20 20 20 20 20 70 43  = pLvl;.      pC
10ce0 73 72 2d 3e 61 50 74 72 5b 69 50 74 72 5d 2e 70  sr->aPtr[iPtr].p
10cf0 53 65 67 20 3d 20 26 70 4c 76 6c 2d 3e 61 52 68  Seg = &pLvl->aRh
10d00 73 5b 69 5d 3b 0a 20 20 20 20 20 20 69 50 74 72  s[i];.      iPtr
10d10 2b 2b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69  ++;.    }..    i
10d20 66 28 20 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 20  f( pLvl->nRight 
10d30 26 26 20 70 4c 76 6c 2d 3e 70 53 70 6c 69 74 4b  && pLvl->pSplitK
10d40 65 79 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 73  ey==0 ){.      s
10d50 6f 72 74 65 64 53 70 6c 69 74 6b 65 79 28 70 43  ortedSplitkey(pC
10d60 73 72 2d 3e 70 44 62 2c 20 70 4c 76 6c 2c 20 70  sr->pDb, pLvl, p
10d70 52 63 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  Rc);.    }.    p
10d80 43 73 72 2d 3e 6e 50 74 72 20 3d 20 69 50 74 72  Csr->nPtr = iPtr
10d90 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20  ;.  }.}..static 
10da0 69 6e 74 20 6d 75 6c 74 69 43 75 72 73 6f 72 41  int multiCursorA
10db0 64 64 41 6c 6c 28 4d 75 6c 74 69 43 75 72 73 6f  ddAll(MultiCurso
10dc0 72 20 2a 70 43 73 72 2c 20 53 6e 61 70 73 68 6f  r *pCsr, Snapsho
10dd0 74 20 2a 70 53 6e 61 70 29 7b 0a 20 20 4c 65 76  t *pSnap){.  Lev
10de0 65 6c 20 2a 70 4c 76 6c 3b 0a 20 20 69 6e 74 20  el *pLvl;.  int 
10df0 6e 50 74 72 20 3d 20 30 3b 0a 20 20 69 6e 74 20  nPtr = 0;.  int 
10e00 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20 20  rc = LSM_OK;..  
10e10 66 6f 72 28 70 4c 76 6c 3d 70 53 6e 61 70 2d 3e  for(pLvl=pSnap->
10e20 70 4c 65 76 65 6c 3b 20 70 4c 76 6c 3b 20 70 4c  pLevel; pLvl; pL
10e30 76 6c 3d 70 4c 76 6c 2d 3e 70 4e 65 78 74 29 7b  vl=pLvl->pNext){
10e40 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 4c  .    /* If the L
10e50 45 56 45 4c 5f 49 4e 43 4f 4d 50 4c 45 54 45 20  EVEL_INCOMPLETE 
10e60 66 6c 61 67 20 69 73 20 73 65 74 2c 20 74 68 65  flag is set, the
10e70 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
10e80 69 73 20 62 65 69 6e 67 0a 20 20 20 20 2a 2a 20  is being.    ** 
10e90 63 61 6c 6c 65 64 20 28 69 6e 64 69 72 65 63 74  called (indirect
10ea0 6c 79 29 20 66 72 6f 6d 20 77 69 74 68 69 6e 20  ly) from within 
10eb0 61 20 73 6f 72 74 65 64 4e 65 77 54 6f 70 6c 65  a sortedNewTople
10ec0 76 65 6c 28 29 20 63 61 6c 6c 20 74 6f 0a 20 20  vel() call to.  
10ed0 20 20 2a 2a 20 63 6f 6e 73 74 72 75 63 74 20 70    ** construct p
10ee0 4c 76 6c 2e 20 49 6e 20 74 68 69 73 20 63 61 73  Lvl. In this cas
10ef0 65 20 69 67 6e 6f 72 65 20 70 4c 76 6c 20 2d 20  e ignore pLvl - 
10f00 74 68 69 73 20 63 75 72 73 6f 72 20 69 73 20 67  this cursor is g
10f10 6f 69 6e 67 20 74 6f 0a 20 20 20 20 2a 2a 20 62  oing to.    ** b
10f20 65 20 75 73 65 64 20 74 6f 20 72 65 74 72 69 65  e used to retrie
10f30 76 65 20 61 20 66 72 65 65 6c 69 73 74 20 65 6e  ve a freelist en
10f40 74 72 79 20 66 72 6f 6d 20 74 68 65 20 4c 53 4d  try from the LSM
10f50 2c 20 61 6e 64 20 74 68 65 20 70 61 72 74 69 61  , and the partia
10f60 6c 6c 79 0a 20 20 20 20 2a 2a 20 63 6f 6d 70 6c  lly.    ** compl
10f70 65 74 65 20 6c 65 76 65 6c 20 6d 61 79 20 63 6f  ete level may co
10f80 6e 66 75 73 65 20 69 74 2e 20 20 2a 2f 0a 20 20  nfuse it.  */.  
10f90 20 20 69 66 28 20 70 4c 76 6c 2d 3e 66 6c 61 67    if( pLvl->flag
10fa0 73 20 26 20 4c 45 56 45 4c 5f 49 4e 43 4f 4d 50  s & LEVEL_INCOMP
10fb0 4c 45 54 45 20 29 20 63 6f 6e 74 69 6e 75 65 3b  LETE ) continue;
10fc0 0a 20 20 20 20 6e 50 74 72 20 2b 3d 20 28 31 20  .    nPtr += (1 
10fd0 2b 20 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 29 3b  + pLvl->nRight);
10fe0 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20  .  }..  assert( 
10ff0 70 43 73 72 2d 3e 61 50 74 72 3d 3d 30 20 29 3b  pCsr->aPtr==0 );
11000 0a 20 20 70 43 73 72 2d 3e 61 50 74 72 20 3d 20  .  pCsr->aPtr = 
11010 6c 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28  lsmMallocZeroRc(
11020 70 43 73 72 2d 3e 70 44 62 2d 3e 70 45 6e 76 2c  pCsr->pDb->pEnv,
11030 20 73 69 7a 65 6f 66 28 53 65 67 6d 65 6e 74 50   sizeof(SegmentP
11040 74 72 29 20 2a 20 6e 50 74 72 2c 20 26 72 63 29  tr) * nPtr, &rc)
11050 3b 0a 0a 20 20 66 6f 72 28 70 4c 76 6c 3d 70 53  ;..  for(pLvl=pS
11060 6e 61 70 2d 3e 70 4c 65 76 65 6c 3b 20 70 4c 76  nap->pLevel; pLv
11070 6c 3b 20 70 4c 76 6c 3d 70 4c 76 6c 2d 3e 70 4e  l; pLvl=pLvl->pN
11080 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20 28 70  ext){.    if( (p
11090 4c 76 6c 2d 3e 66 6c 61 67 73 20 26 20 4c 45 56  Lvl->flags & LEV
110a0 45 4c 5f 49 4e 43 4f 4d 50 4c 45 54 45 29 3d 3d  EL_INCOMPLETE)==
110b0 30 20 29 7b 0a 20 20 20 20 20 20 6d 75 6c 74 69  0 ){.      multi
110c0 43 75 72 73 6f 72 41 64 64 4f 6e 65 28 70 43 73  CursorAddOne(pCs
110d0 72 2c 20 70 4c 76 6c 2c 20 26 72 63 29 3b 0a 20  r, pLvl, &rc);. 
110e0 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
110f0 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
11100 20 69 6e 74 20 6d 75 6c 74 69 43 75 72 73 6f 72   int multiCursor
11110 49 6e 69 74 28 4d 75 6c 74 69 43 75 72 73 6f 72  Init(MultiCursor
11120 20 2a 70 43 73 72 2c 20 53 6e 61 70 73 68 6f 74   *pCsr, Snapshot
11130 20 2a 70 53 6e 61 70 29 7b 0a 20 20 69 6e 74 20   *pSnap){.  int 
11140 72 63 3b 0a 20 20 72 63 20 3d 20 6d 75 6c 74 69  rc;.  rc = multi
11150 43 75 72 73 6f 72 41 64 64 41 6c 6c 28 70 43 73  CursorAddAll(pCs
11160 72 2c 20 70 53 6e 61 70 29 3b 0a 20 20 69 66 28  r, pSnap);.  if(
11170 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20   rc==LSM_OK ){. 
11180 20 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75 72     rc = multiCur
11190 73 6f 72 41 64 64 54 72 65 65 28 70 43 73 72 2c  sorAddTree(pCsr,
111a0 20 70 53 6e 61 70 2c 20 54 52 45 45 5f 42 4f 54   pSnap, TREE_BOT
111b0 48 29 3b 0a 20 20 7d 0a 20 20 70 43 73 72 2d 3e  H);.  }.  pCsr->
111c0 66 6c 61 67 73 20 7c 3d 20 28 43 55 52 53 4f 52  flags |= (CURSOR
111d0 5f 49 47 4e 4f 52 45 5f 53 59 53 54 45 4d 20 7c  _IGNORE_SYSTEM |
111e0 20 43 55 52 53 4f 52 5f 49 47 4e 4f 52 45 5f 44   CURSOR_IGNORE_D
111f0 45 4c 45 54 45 29 3b 0a 20 20 72 65 74 75 72 6e  ELETE);.  return
11200 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 4d   rc;.}..static M
11210 75 6c 74 69 43 75 72 73 6f 72 20 2a 6d 75 6c 74  ultiCursor *mult
11220 69 43 75 72 73 6f 72 4e 65 77 28 6c 73 6d 5f 64  iCursorNew(lsm_d
11230 62 20 2a 64 62 2c 20 69 6e 74 20 2a 70 52 63 29  b *db, int *pRc)
11240 7b 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  {.  MultiCursor 
11250 2a 70 43 73 72 3b 0a 20 20 70 43 73 72 20 3d 20  *pCsr;.  pCsr = 
11260 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 29 6c  (MultiCursor *)l
11270 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28 64  smMallocZeroRc(d
11280 62 2d 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66 28  b->pEnv, sizeof(
11290 4d 75 6c 74 69 43 75 72 73 6f 72 29 2c 20 70 52  MultiCursor), pR
112a0 63 29 3b 0a 20 20 69 66 28 20 70 43 73 72 20 29  c);.  if( pCsr )
112b0 7b 0a 20 20 20 20 70 43 73 72 2d 3e 70 4e 65 78  {.    pCsr->pNex
112c0 74 20 3d 20 64 62 2d 3e 70 43 73 72 3b 0a 20 20  t = db->pCsr;.  
112d0 20 20 64 62 2d 3e 70 43 73 72 20 3d 20 70 43 73    db->pCsr = pCs
112e0 72 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 44 62  r;.    pCsr->pDb
112f0 20 3d 20 64 62 3b 0a 20 20 7d 0a 20 20 72 65 74   = db;.  }.  ret
11300 75 72 6e 20 70 43 73 72 3b 0a 7d 0a 0a 0a 76 6f  urn pCsr;.}...vo
11310 69 64 20 6c 73 6d 53 6f 72 74 65 64 52 65 6d 61  id lsmSortedRema
11320 70 28 6c 73 6d 5f 64 62 20 2a 70 44 62 29 7b 0a  p(lsm_db *pDb){.
11330 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70    MultiCursor *p
11340 43 73 72 3b 0a 20 20 66 6f 72 28 70 43 73 72 3d  Csr;.  for(pCsr=
11350 70 44 62 2d 3e 70 43 73 72 3b 20 70 43 73 72 3b  pDb->pCsr; pCsr;
11360 20 70 43 73 72 3d 70 43 73 72 2d 3e 70 4e 65 78   pCsr=pCsr->pNex
11370 74 29 7b 0a 20 20 20 20 69 6e 74 20 69 50 74 72  t){.    int iPtr
11380 3b 0a 20 20 20 20 69 66 28 20 70 43 73 72 2d 3e  ;.    if( pCsr->
11390 70 42 74 43 73 72 20 29 7b 0a 20 20 20 20 20 20  pBtCsr ){.      
113a0 62 74 72 65 65 43 75 72 73 6f 72 4c 6f 61 64 4b  btreeCursorLoadK
113b0 65 79 28 70 43 73 72 2d 3e 70 42 74 43 73 72 29  ey(pCsr->pBtCsr)
113c0 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28  ;.    }.    for(
113d0 69 50 74 72 3d 30 3b 20 69 50 74 72 3c 70 43 73  iPtr=0; iPtr<pCs
113e0 72 2d 3e 6e 50 74 72 3b 20 69 50 74 72 2b 2b 29  r->nPtr; iPtr++)
113f0 7b 0a 20 20 20 20 20 20 73 65 67 6d 65 6e 74 50  {.      segmentP
11400 74 72 4c 6f 61 64 43 65 6c 6c 28 26 70 43 73 72  trLoadCell(&pCsr
11410 2d 3e 61 50 74 72 5b 69 50 74 72 5d 2c 20 70 43  ->aPtr[iPtr], pC
11420 73 72 2d 3e 61 50 74 72 5b 69 50 74 72 5d 2e 69  sr->aPtr[iPtr].i
11430 43 65 6c 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  Cell);.    }.  }
11440 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
11450 6d 75 6c 74 69 43 75 72 73 6f 72 52 65 61 64 53  multiCursorReadS
11460 65 70 61 72 61 74 6f 72 73 28 4d 75 6c 74 69 43  eparators(MultiC
11470 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20  ursor *pCsr){.  
11480 69 66 28 20 70 43 73 72 2d 3e 6e 50 74 72 3e 30  if( pCsr->nPtr>0
11490 20 29 7b 0a 20 20 20 20 70 43 73 72 2d 3e 66 6c   ){.    pCsr->fl
114a0 61 67 73 20 7c 3d 20 43 55 52 53 4f 52 5f 52 45  ags |= CURSOR_RE
114b0 41 44 5f 53 45 50 41 52 41 54 4f 52 53 3b 0a 20  AD_SEPARATORS;. 
114c0 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 48 61 76 65   }.}../*.** Have
114d0 20 74 68 69 73 20 63 75 72 73 6f 72 20 73 6b 69   this cursor ski
114e0 70 20 6f 76 65 72 20 53 4f 52 54 45 44 5f 44 45  p over SORTED_DE
114f0 4c 45 54 45 20 65 6e 74 72 69 65 73 2e 0a 2a 2f  LETE entries..*/
11500 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 75 6c  .static void mul
11510 74 69 43 75 72 73 6f 72 49 67 6e 6f 72 65 44 65  tiCursorIgnoreDe
11520 6c 65 74 65 28 4d 75 6c 74 69 43 75 72 73 6f 72  lete(MultiCursor
11530 20 2a 70 43 73 72 29 7b 0a 20 20 69 66 28 20 70   *pCsr){.  if( p
11540 43 73 72 20 29 20 70 43 73 72 2d 3e 66 6c 61 67  Csr ) pCsr->flag
11550 73 20 7c 3d 20 43 55 52 53 4f 52 5f 49 47 4e 4f  s |= CURSOR_IGNO
11560 52 45 5f 44 45 4c 45 54 45 3b 0a 7d 0a 0a 2f 2a  RE_DELETE;.}../*
11570 0a 2a 2a 20 49 66 20 74 68 65 20 66 72 65 65 2d  .** If the free-
11580 62 6c 6f 63 6b 20 6c 69 73 74 20 69 73 20 6e 6f  block list is no
11590 74 20 65 6d 70 74 79 2c 20 74 68 65 6e 20 68 61  t empty, then ha
115a0 76 65 20 74 68 69 73 20 63 75 72 73 6f 72 20 76  ve this cursor v
115b0 69 73 69 74 20 61 20 6b 65 79 0a 2a 2a 20 77 69  isit a key.** wi
115c0 74 68 20 28 61 29 20 74 68 65 20 73 79 73 74 65  th (a) the syste
115d0 6d 20 62 69 74 20 73 65 74 2c 20 61 6e 64 20 28  m bit set, and (
115e0 62 29 20 74 68 65 20 6b 65 79 20 22 46 52 45 45  b) the key "FREE
115f0 4c 49 53 54 22 20 61 6e 64 20 28 63 29 20 61 20  LIST" and (c) a 
11600 76 61 6c 75 65 20 0a 2a 2a 20 62 6c 6f 62 20 63  value .** blob c
11610 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 73 65  ontaining the se
11620 72 69 61 6c 69 7a 65 64 20 66 72 65 65 2d 62 6c  rialized free-bl
11630 6f 63 6b 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61  ock list..*/.sta
11640 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 43 75 72  tic int multiCur
11650 73 6f 72 56 69 73 69 74 46 72 65 65 6c 69 73 74  sorVisitFreelist
11660 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43  (MultiCursor *pC
11670 73 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  sr){.  int rc = 
11680 4c 53 4d 5f 4f 4b 3b 0a 20 20 70 43 73 72 2d 3e  LSM_OK;.  pCsr->
11690 66 6c 61 67 73 20 7c 3d 20 43 55 52 53 4f 52 5f  flags |= CURSOR_
116a0 46 4c 55 53 48 5f 46 52 45 45 4c 49 53 54 3b 0a  FLUSH_FREELIST;.
116b0 20 20 70 43 73 72 2d 3e 70 53 79 73 74 65 6d 56    pCsr->pSystemV
116c0 61 6c 20 3d 20 6c 73 6d 4d 61 6c 6c 6f 63 52 63  al = lsmMallocRc
116d0 28 70 43 73 72 2d 3e 70 44 62 2d 3e 70 45 6e 76  (pCsr->pDb->pEnv
116e0 2c 20 34 20 2b 20 38 2c 20 26 72 63 29 3b 0a 20  , 4 + 8, &rc);. 
116f0 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
11700 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 6e  *.** Allocate an
11710 64 20 72 65 74 75 72 6e 20 61 20 6e 65 77 20 64  d return a new d
11720 61 74 61 62 61 73 65 20 63 75 72 73 6f 72 2e 0a  atabase cursor..
11730 2a 2a 0a 2a 2a 20 54 68 69 73 20 6d 65 74 68 6f  **.** This metho
11740 64 20 73 68 6f 75 6c 64 20 6f 6e 6c 79 20 62 65  d should only be
11750 20 63 61 6c 6c 65 64 20 74 6f 20 61 6c 6c 6f 63   called to alloc
11760 61 74 65 20 75 73 65 72 20 63 75 72 73 6f 72 73  ate user cursors
11770 2e 20 41 73 20 69 74 20 6d 61 79 0a 2a 2a 20 72  . As it may.** r
11780 65 63 79 63 6c 65 20 61 20 63 75 72 73 6f 72 20  ecycle a cursor 
11790 66 72 6f 6d 20 6c 73 6d 5f 64 62 2e 70 43 73 72  from lsm_db.pCsr
117a0 43 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74 20 6c 73  Cache..*/.int ls
117b0 6d 4d 43 75 72 73 6f 72 4e 65 77 28 0a 20 20 6c  mMCursorNew(.  l
117c0 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20 20 20  sm_db *pDb,     
117d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
117e0 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c  * Database handl
117f0 65 20 2a 2f 0a 20 20 4d 75 6c 74 69 43 75 72 73  e */.  MultiCurs
11800 6f 72 20 2a 2a 70 70 43 73 72 20 20 20 20 20 20  or **ppCsr      
11810 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 41         /* OUT: A
11820 6c 6c 6f 63 61 74 65 64 20 63 75 72 73 6f 72 20  llocated cursor 
11830 2a 2f 0a 29 7b 0a 20 20 4d 75 6c 74 69 43 75 72  */.){.  MultiCur
11840 73 6f 72 20 2a 70 43 73 72 20 3d 20 30 3b 0a 20  sor *pCsr = 0;. 
11850 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
11860 3b 0a 0a 20 20 69 66 28 20 70 44 62 2d 3e 70 43  ;..  if( pDb->pC
11870 73 72 43 61 63 68 65 20 29 7b 0a 20 20 20 20 69  srCache ){.    i
11880 6e 74 20 62 4f 6c 64 3b 20 20 20 20 20 20 20 20  nt bOld;        
11890 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
118a0 54 72 75 65 20 69 66 20 74 68 65 72 65 20 69 73  True if there is
118b0 20 61 6e 20 6f 6c 64 20 69 6e 2d 6d 65 6d 6f 72   an old in-memor
118c0 79 20 74 72 65 65 20 2a 2f 0a 0a 20 20 20 20 2f  y tree */..    /
118d0 2a 20 52 65 6d 6f 76 65 20 61 20 63 75 72 73 6f  * Remove a curso
118e0 72 20 66 72 6f 6d 20 74 68 65 20 70 43 73 72 43  r from the pCsrC
118f0 61 63 68 65 20 6c 69 73 74 20 61 6e 64 20 61 64  ache list and ad
11900 64 20 69 74 20 74 6f 20 74 68 65 20 6f 70 65 6e  d it to the open
11910 20 6c 69 73 74 2e 20 2a 2f 0a 20 20 20 20 70 43   list. */.    pC
11920 73 72 20 3d 20 70 44 62 2d 3e 70 43 73 72 43 61  sr = pDb->pCsrCa
11930 63 68 65 3b 0a 20 20 20 20 70 44 62 2d 3e 70 43  che;.    pDb->pC
11940 73 72 43 61 63 68 65 20 3d 20 70 43 73 72 2d 3e  srCache = pCsr->
11950 70 4e 65 78 74 3b 0a 20 20 20 20 70 43 73 72 2d  pNext;.    pCsr-
11960 3e 70 4e 65 78 74 20 3d 20 70 44 62 2d 3e 70 43  >pNext = pDb->pC
11970 73 72 3b 0a 20 20 20 20 70 44 62 2d 3e 70 43 73  sr;.    pDb->pCs
11980 72 20 3d 20 70 43 73 72 3b 0a 0a 20 20 20 20 2f  r = pCsr;..    /
11990 2a 20 54 68 65 20 63 75 72 73 6f 72 20 63 61 6e  * The cursor can
119a0 20 61 6c 6d 6f 73 74 20 62 65 20 75 73 65 64 20   almost be used 
119b0 61 73 20 69 73 2c 20 65 78 63 65 70 74 20 74 68  as is, except th
119c0 61 74 20 74 68 65 20 6f 6c 64 20 69 6e 2d 6d 65  at the old in-me
119d0 6d 6f 72 79 0a 20 20 20 20 2a 2a 20 74 72 65 65  mory.    ** tree
119e0 20 63 75 72 73 6f 72 20 6d 61 79 20 62 65 20 70   cursor may be p
119f0 72 65 73 65 6e 74 20 61 6e 64 20 6e 6f 74 20 72  resent and not r
11a00 65 71 75 69 72 65 64 2c 20 6f 72 20 72 65 71 75  equired, or requ
11a10 69 72 65 64 20 61 6e 64 20 6e 6f 74 0a 20 20 20  ired and not.   
11a20 20 2a 2a 20 70 72 65 73 65 6e 74 2e 20 46 69 78   ** present. Fix
11a30 20 74 68 69 73 20 69 66 20 72 65 71 75 69 72 65   this if require
11a40 64 2e 20 20 2a 2f 0a 20 20 20 20 62 4f 6c 64 20  d.  */.    bOld 
11a50 3d 20 28 6c 73 6d 54 72 65 65 48 61 73 4f 6c 64  = (lsmTreeHasOld
11a60 28 70 44 62 29 20 26 26 20 70 44 62 2d 3e 74 72  (pDb) && pDb->tr
11a70 65 65 68 64 72 2e 69 4f 6c 64 4c 6f 67 21 3d 70  eehdr.iOldLog!=p
11a80 44 62 2d 3e 70 43 6c 69 65 6e 74 2d 3e 69 4c 6f  Db->pClient->iLo
11a90 67 4f 66 66 29 3b 0a 20 20 20 20 69 66 28 20 21  gOff);.    if( !
11aa0 62 4f 6c 64 20 26 26 20 70 43 73 72 2d 3e 61 70  bOld && pCsr->ap
11ab0 54 72 65 65 43 73 72 5b 31 5d 20 29 7b 0a 20 20  TreeCsr[1] ){.  
11ac0 20 20 20 20 6c 73 6d 54 72 65 65 43 75 72 73 6f      lsmTreeCurso
11ad0 72 44 65 73 74 72 6f 79 28 70 43 73 72 2d 3e 61  rDestroy(pCsr->a
11ae0 70 54 72 65 65 43 73 72 5b 31 5d 29 3b 0a 20 20  pTreeCsr[1]);.  
11af0 20 20 20 20 70 43 73 72 2d 3e 61 70 54 72 65 65      pCsr->apTree
11b00 43 73 72 5b 31 5d 20 3d 20 30 3b 0a 20 20 20 20  Csr[1] = 0;.    
11b10 7d 65 6c 73 65 20 69 66 28 20 62 4f 6c 64 20 26  }else if( bOld &
11b20 26 20 21 70 43 73 72 2d 3e 61 70 54 72 65 65 43  & !pCsr->apTreeC
11b30 73 72 5b 31 5d 20 29 7b 0a 20 20 20 20 20 20 72  sr[1] ){.      r
11b40 63 20 3d 20 6c 73 6d 54 72 65 65 43 75 72 73 6f  c = lsmTreeCurso
11b50 72 4e 65 77 28 70 44 62 2c 20 31 2c 20 26 70 43  rNew(pDb, 1, &pC
11b60 73 72 2d 3e 61 70 54 72 65 65 43 73 72 5b 31 5d  sr->apTreeCsr[1]
11b70 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 43  );.    }..    pC
11b80 73 72 2d 3e 66 6c 61 67 73 20 3d 20 28 43 55 52  sr->flags = (CUR
11b90 53 4f 52 5f 49 47 4e 4f 52 45 5f 53 59 53 54 45  SOR_IGNORE_SYSTE
11ba0 4d 20 7c 20 43 55 52 53 4f 52 5f 49 47 4e 4f 52  M | CURSOR_IGNOR
11bb0 45 5f 44 45 4c 45 54 45 29 3b 0a 0a 20 20 7d 65  E_DELETE);..  }e
11bc0 6c 73 65 7b 0a 20 20 20 20 70 43 73 72 20 3d 20  lse{.    pCsr = 
11bd0 6d 75 6c 74 69 43 75 72 73 6f 72 4e 65 77 28 70  multiCursorNew(p
11be0 44 62 2c 20 26 72 63 29 3b 0a 20 20 20 20 69 66  Db, &rc);.    if
11bf0 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 20 72  ( rc==LSM_OK ) r
11c00 63 20 3d 20 6d 75 6c 74 69 43 75 72 73 6f 72 49  c = multiCursorI
11c10 6e 69 74 28 70 43 73 72 2c 20 70 44 62 2d 3e 70  nit(pCsr, pDb->p
11c20 43 6c 69 65 6e 74 29 3b 0a 20 20 7d 0a 0a 20 20  Client);.  }..  
11c30 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29  if( rc!=LSM_OK )
11c40 7b 0a 20 20 20 20 6c 73 6d 4d 43 75 72 73 6f 72  {.    lsmMCursor
11c50 43 6c 6f 73 65 28 70 43 73 72 2c 20 30 29 3b 0a  Close(pCsr, 0);.
11c60 20 20 20 20 70 43 73 72 20 3d 20 30 3b 0a 20 20      pCsr = 0;.  
11c70 7d 0a 20 20 61 73 73 65 72 74 28 20 28 72 63 3d  }.  assert( (rc=
11c80 3d 4c 53 4d 5f 4f 4b 29 3d 3d 28 70 43 73 72 21  =LSM_OK)==(pCsr!
11c90 3d 30 29 20 29 3b 0a 20 20 2a 70 70 43 73 72 20  =0) );.  *ppCsr 
11ca0 3d 20 70 43 73 72 3b 0a 20 20 72 65 74 75 72 6e  = pCsr;.  return
11cb0 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69   rc;.}..static i
11cc0 6e 74 20 6d 75 6c 74 69 43 75 72 73 6f 72 47 65  nt multiCursorGe
11cd0 74 56 61 6c 28 0a 20 20 4d 75 6c 74 69 43 75 72  tVal(.  MultiCur
11ce0 73 6f 72 20 2a 70 43 73 72 2c 20 0a 20 20 69 6e  sor *pCsr, .  in
11cf0 74 20 69 56 61 6c 2c 20 0a 20 20 76 6f 69 64 20  t iVal, .  void 
11d00 2a 2a 70 70 56 61 6c 2c 20 0a 20 20 69 6e 74 20  **ppVal, .  int 
11d10 2a 70 6e 56 61 6c 0a 29 7b 0a 20 20 69 6e 74 20  *pnVal.){.  int 
11d20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20 20  rc = LSM_OK;..  
11d30 2a 70 70 56 61 6c 20 3d 20 30 3b 0a 20 20 2a 70  *ppVal = 0;.  *p
11d40 6e 56 61 6c 20 3d 20 30 3b 0a 0a 20 20 73 77 69  nVal = 0;..  swi
11d50 74 63 68 28 20 69 56 61 6c 20 29 7b 0a 20 20 20  tch( iVal ){.   
11d60 20 63 61 73 65 20 43 55 52 53 4f 52 5f 44 41 54   case CURSOR_DAT
11d70 41 5f 54 52 45 45 30 3a 0a 20 20 20 20 63 61 73  A_TREE0:.    cas
11d80 65 20 43 55 52 53 4f 52 5f 44 41 54 41 5f 54 52  e CURSOR_DATA_TR
11d90 45 45 31 3a 20 7b 0a 20 20 20 20 20 20 54 72 65  EE1: {.      Tre
11da0 65 43 75 72 73 6f 72 20 2a 70 54 72 65 65 43 73  eCursor *pTreeCs
11db0 72 20 3d 20 70 43 73 72 2d 3e 61 70 54 72 65 65  r = pCsr->apTree
11dc0 43 73 72 5b 69 56 61 6c 2d 43 55 52 53 4f 52 5f  Csr[iVal-CURSOR_
11dd0 44 41 54 41 5f 54 52 45 45 30 5d 3b 0a 20 20 20  DATA_TREE0];.   
11de0 20 20 20 69 66 28 20 6c 73 6d 54 72 65 65 43 75     if( lsmTreeCu
11df0 72 73 6f 72 56 61 6c 69 64 28 70 54 72 65 65 43  rsorValid(pTreeC
11e00 73 72 29 20 29 7b 0a 20 20 20 20 20 20 20 20 6c  sr) ){.        l
11e10 73 6d 54 72 65 65 43 75 72 73 6f 72 56 61 6c 75  smTreeCursorValu
11e20 65 28 70 54 72 65 65 43 73 72 2c 20 70 70 56 61  e(pTreeCsr, ppVa
11e30 6c 2c 20 70 6e 56 61 6c 29 3b 0a 20 20 20 20 20  l, pnVal);.     
11e40 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
11e50 2a 70 70 56 61 6c 20 3d 20 30 3b 0a 20 20 20 20  *ppVal = 0;.    
11e60 20 20 20 20 2a 70 6e 56 61 6c 20 3d 20 30 3b 0a      *pnVal = 0;.
11e70 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72        }.      br
11e80 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  eak;.    }..    
11e90 63 61 73 65 20 43 55 52 53 4f 52 5f 44 41 54 41  case CURSOR_DATA
11ea0 5f 53 59 53 54 45 4d 3a 20 7b 0a 20 20 20 20 20  _SYSTEM: {.     
11eb0 20 53 6e 61 70 73 68 6f 74 20 2a 70 57 6f 72 6b   Snapshot *pWork
11ec0 65 72 20 3d 20 70 43 73 72 2d 3e 70 44 62 2d 3e  er = pCsr->pDb->
11ed0 70 57 6f 72 6b 65 72 3b 0a 20 20 20 20 20 20 69  pWorker;.      i
11ee0 66 28 20 70 57 6f 72 6b 65 72 20 0a 20 20 20 20  f( pWorker .    
11ef0 20 20 20 26 26 20 28 70 43 73 72 2d 3e 69 46 72     && (pCsr->iFr
11f00 65 65 20 25 20 32 29 3d 3d 30 0a 20 20 20 20 20  ee % 2)==0.     
11f10 20 20 26 26 20 70 43 73 72 2d 3e 69 46 72 65 65    && pCsr->iFree
11f20 20 3c 20 28 70 57 6f 72 6b 65 72 2d 3e 66 72 65   < (pWorker->fre
11f30 65 6c 69 73 74 2e 6e 45 6e 74 72 79 2a 32 29 0a  elist.nEntry*2).
11f40 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20        ){.       
11f50 20 69 6e 74 20 69 45 6e 74 72 79 20 3d 20 70 57   int iEntry = pW
11f60 6f 72 6b 65 72 2d 3e 66 72 65 65 6c 69 73 74 2e  orker->freelist.
11f70 6e 45 6e 74 72 79 20 2d 20 31 20 2d 20 28 70 43  nEntry - 1 - (pC
11f80 73 72 2d 3e 69 46 72 65 65 20 2f 20 32 29 3b 0a  sr->iFree / 2);.
11f90 20 20 20 20 20 20 20 20 75 38 20 2a 61 56 61 6c          u8 *aVal
11fa0 20 3d 20 26 28 28 75 38 20 2a 29 28 70 43 73 72   = &((u8 *)(pCsr
11fb0 2d 3e 70 53 79 73 74 65 6d 56 61 6c 29 29 5b 34  ->pSystemVal))[4
11fc0 5d 3b 0a 20 20 20 20 20 20 20 20 6c 73 6d 50 75  ];.        lsmPu
11fd0 74 55 36 34 28 61 56 61 6c 2c 20 70 57 6f 72 6b  tU64(aVal, pWork
11fe0 65 72 2d 3e 66 72 65 65 6c 69 73 74 2e 61 45 6e  er->freelist.aEn
11ff0 74 72 79 5b 69 45 6e 74 72 79 5d 2e 69 49 64 29  try[iEntry].iId)
12000 3b 0a 20 20 20 20 20 20 20 20 2a 70 70 56 61 6c  ;.        *ppVal
12010 20 3d 20 61 56 61 6c 3b 0a 20 20 20 20 20 20 20   = aVal;.       
12020 20 2a 70 6e 56 61 6c 20 3d 20 38 3b 0a 20 20 20   *pnVal = 8;.   
12030 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b     }.      break
12040 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 64 65 66  ;.    }..    def
12050 61 75 6c 74 3a 20 7b 0a 20 20 20 20 20 20 69 6e  ault: {.      in
12060 74 20 69 50 74 72 20 3d 20 69 56 61 6c 2d 43 55  t iPtr = iVal-CU
12070 52 53 4f 52 5f 44 41 54 41 5f 53 45 47 4d 45 4e  RSOR_DATA_SEGMEN
12080 54 3b 0a 20 20 20 20 20 20 69 66 28 20 69 50 74  T;.      if( iPt
12090 72 3c 70 43 73 72 2d 3e 6e 50 74 72 20 29 7b 0a  r<pCsr->nPtr ){.
120a0 20 20 20 20 20 20 20 20 53 65 67 6d 65 6e 74 50          SegmentP
120b0 74 72 20 2a 70 50 74 72 20 3d 20 26 70 43 73 72  tr *pPtr = &pCsr
120c0 2d 3e 61 50 74 72 5b 69 50 74 72 5d 3b 0a 20 20  ->aPtr[iPtr];.  
120d0 20 20 20 20 20 20 69 66 28 20 70 50 74 72 2d 3e        if( pPtr->
120e0 70 50 67 20 29 7b 0a 20 20 20 20 20 20 20 20 20  pPg ){.         
120f0 20 2a 70 70 56 61 6c 20 3d 20 70 50 74 72 2d 3e   *ppVal = pPtr->
12100 70 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 20 20  pVal;.          
12110 2a 70 6e 56 61 6c 20 3d 20 70 50 74 72 2d 3e 6e  *pnVal = pPtr->n
12120 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  Val;.        }. 
12130 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
12140 0a 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d  ..  assert( rc==
12150 4c 53 4d 5f 4f 4b 20 7c 7c 20 28 2a 70 70 56 61  LSM_OK || (*ppVa
12160 6c 3d 3d 30 20 26 26 20 2a 70 6e 56 61 6c 3d 3d  l==0 && *pnVal==
12170 30 29 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  0) );.  return r
12180 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
12190 20 6d 75 6c 74 69 43 75 72 73 6f 72 41 64 76 61   multiCursorAdva
121a0 6e 63 65 28 4d 75 6c 74 69 43 75 72 73 6f 72 20  nce(MultiCursor 
121b0 2a 70 43 73 72 2c 20 69 6e 74 20 62 52 65 76 65  *pCsr, int bReve
121c0 72 73 65 29 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  rse);../*.** Thi
121d0 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
121e0 6c 6c 65 64 20 62 79 20 77 6f 72 6b 65 72 20 63  lled by worker c
121f0 6f 6e 6e 65 63 74 69 6f 6e 73 20 74 6f 20 77 61  onnections to wa
12200 6c 6b 20 74 68 65 20 70 61 72 74 20 6f 66 20 74  lk the part of t
12210 68 65 0a 2a 2a 20 66 72 65 65 2d 6c 69 73 74 20  he.** free-list 
12220 73 74 6f 72 65 64 20 77 69 74 68 69 6e 20 74 68  stored within th
12230 65 20 4c 53 4d 20 64 61 74 61 20 73 74 72 75 63  e LSM data struc
12240 74 75 72 65 2e 0a 2a 2f 0a 69 6e 74 20 6c 73 6d  ture..*/.int lsm
12250 53 6f 72 74 65 64 57 61 6c 6b 46 72 65 65 6c 69  SortedWalkFreeli
12260 73 74 28 0a 20 20 6c 73 6d 5f 64 62 20 2a 70 44  st(.  lsm_db *pD
12270 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
12280 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
12290 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e  e handle */.  in
122a0 74 20 62 52 65 76 65 72 73 65 2c 20 20 20 20 20  t bReverse,     
122b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
122c0 20 54 72 75 65 20 74 6f 20 69 74 65 72 61 74 65   True to iterate
122d0 20 66 72 6f 6d 20 6c 61 72 67 65 73 74 20 74 6f   from largest to
122e0 20 73 6d 61 6c 6c 65 73 74 20 2a 2f 0a 20 20 69   smallest */.  i
122f0 6e 74 20 28 2a 78 29 28 76 6f 69 64 20 2a 2c 20  nt (*x)(void *, 
12300 69 6e 74 2c 20 69 36 34 29 2c 20 20 20 20 20 2f  int, i64),     /
12310 2a 20 43 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74  * Callback funct
12320 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  ion */.  void *p
12330 43 74 78 20 20 20 20 20 20 20 20 20 20 20 20 20  Ctx             
12340 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73           /* Firs
12350 74 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 70 61  t argument to pa
12360 73 73 20 74 6f 20 63 61 6c 6c 62 61 63 6b 20 2a  ss to callback *
12370 2f 0a 29 7b 0a 20 20 4d 75 6c 74 69 43 75 72 73  /.){.  MultiCurs
12380 6f 72 20 2a 70 43 73 72 3b 20 20 20 20 20 20 20  or *pCsr;       
12390 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73 6f 72         /* Cursor
123a0 20 75 73 65 64 20 74 6f 20 72 65 61 64 20 64 62   used to read db
123b0 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c   */.  int rc = L
123c0 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  SM_OK;          
123d0 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
123e0 43 6f 64 65 20 2a 2f 0a 20 20 53 6e 61 70 73 68  Code */.  Snapsh
123f0 6f 74 20 2a 70 53 6e 61 70 20 3d 20 30 3b 0a 0a  ot *pSnap = 0;..
12400 20 20 61 73 73 65 72 74 28 20 70 44 62 2d 3e 70    assert( pDb->p
12410 57 6f 72 6b 65 72 20 29 3b 0a 20 20 69 66 28 20  Worker );.  if( 
12420 70 44 62 2d 3e 62 49 6e 63 72 4d 65 72 67 65 20  pDb->bIncrMerge 
12430 29 7b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 43  ){.    rc = lsmC
12440 68 65 63 6b 70 6f 69 6e 74 44 65 73 65 72 69 61  heckpointDeseria
12450 6c 69 7a 65 28 70 44 62 2c 20 30 2c 20 70 44 62  lize(pDb, 0, pDb
12460 2d 3e 70 53 68 6d 68 64 72 2d 3e 61 53 6e 61 70  ->pShmhdr->aSnap
12470 31 2c 20 26 70 53 6e 61 70 29 3b 0a 20 20 20 20  1, &pSnap);.    
12480 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29  if( rc!=LSM_OK )
12490 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 65   return rc;.  }e
124a0 6c 73 65 7b 0a 20 20 20 20 70 53 6e 61 70 20 3d  lse{.    pSnap =
124b0 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 3b 0a 20   pDb->pWorker;. 
124c0 20 7d 0a 0a 20 20 70 43 73 72 20 3d 20 6d 75 6c   }..  pCsr = mul
124d0 74 69 43 75 72 73 6f 72 4e 65 77 28 70 44 62 2c  tiCursorNew(pDb,
124e0 20 26 72 63 29 3b 0a 20 20 69 66 28 20 70 43 73   &rc);.  if( pCs
124f0 72 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 6d 75  r ){.    rc = mu
12500 6c 74 69 43 75 72 73 6f 72 41 64 64 41 6c 6c 28  ltiCursorAddAll(
12510 70 43 73 72 2c 20 70 53 6e 61 70 29 3b 0a 20 20  pCsr, pSnap);.  
12520 20 20 70 43 73 72 2d 3e 66 6c 61 67 73 20 7c 3d    pCsr->flags |=
12530 20 43 55 52 53 4f 52 5f 49 47 4e 4f 52 45 5f 44   CURSOR_IGNORE_D
12540 45 4c 45 54 45 3b 0a 20 20 7d 0a 20 20 0a 20 20  ELETE;.  }.  .  
12550 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
12560 7b 0a 20 20 20 20 69 66 28 20 62 52 65 76 65 72  {.    if( bRever
12570 73 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72  se==0 ){.      r
12580 63 20 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 4c 61  c = lsmMCursorLa
12590 73 74 28 70 43 73 72 29 3b 0a 20 20 20 20 7d 65  st(pCsr);.    }e
125a0 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  lse{.      rc = 
125b0 6c 73 6d 4d 43 75 72 73 6f 72 53 65 65 6b 28 70  lsmMCursorSeek(p
125c0 43 73 72 2c 20 31 2c 20 22 22 2c 20 30 2c 20 4c  Csr, 1, "", 0, L
125d0 53 4d 5f 53 45 45 4b 5f 47 45 29 3b 0a 20 20 20  SM_SEEK_GE);.   
125e0 20 7d 0a 0a 20 20 20 20 77 68 69 6c 65 28 20 72   }..    while( r
125f0 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 6c 73 6d  c==LSM_OK && lsm
12600 4d 43 75 72 73 6f 72 56 61 6c 69 64 28 70 43 73  MCursorValid(pCs
12610 72 29 20 26 26 20 72 74 49 73 53 79 73 74 65 6d  r) && rtIsSystem
12620 28 70 43 73 72 2d 3e 65 54 79 70 65 29 20 29 7b  (pCsr->eType) ){
12630 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70 4b 65  .      void *pKe
12640 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 0a 20 20 20  y; int nKey;.   
12650 20 20 20 76 6f 69 64 20 2a 70 56 61 6c 3b 20 69     void *pVal; i
12660 6e 74 20 6e 56 61 6c 3b 0a 0a 20 20 20 20 20 20  nt nVal;..      
12670 72 63 20 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 4b  rc = lsmMCursorK
12680 65 79 28 70 43 73 72 2c 20 26 70 4b 65 79 2c 20  ey(pCsr, &pKey, 
12690 26 6e 4b 65 79 29 3b 0a 20 20 20 20 20 20 69 66  &nKey);.      if
126a0 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 20 72  ( rc==LSM_OK ) r
126b0 63 20 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 56 61  c = lsmMCursorVa
126c0 6c 75 65 28 70 43 73 72 2c 20 26 70 56 61 6c 2c  lue(pCsr, &pVal,
126d0 20 26 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 69   &nVal);.      i
126e0 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26  f( rc==LSM_OK &&
126f0 20 28 6e 4b 65 79 21 3d 34 20 7c 7c 20 6e 56 61   (nKey!=4 || nVa
12700 6c 21 3d 38 29 20 29 20 72 63 20 3d 20 4c 53 4d  l!=8) ) rc = LSM
12710 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a 0a  _CORRUPT_BKPT;..
12720 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53        if( rc==LS
12730 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  M_OK ){.        
12740 69 6e 74 20 69 42 6c 6b 3b 0a 20 20 20 20 20 20  int iBlk;.      
12750 20 20 69 36 34 20 69 53 6e 61 70 3b 0a 20 20 20    i64 iSnap;.   
12760 20 20 20 20 20 69 42 6c 6b 20 3d 20 28 69 6e 74       iBlk = (int
12770 29 28 7e 28 6c 73 6d 47 65 74 55 33 32 28 28 75  )(~(lsmGetU32((u
12780 38 20 2a 29 70 4b 65 79 29 29 29 3b 0a 20 20 20  8 *)pKey)));.   
12790 20 20 20 20 20 69 53 6e 61 70 20 3d 20 28 69 36       iSnap = (i6
127a0 34 29 6c 73 6d 47 65 74 55 36 34 28 28 75 38 20  4)lsmGetU64((u8 
127b0 2a 29 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 20  *)pVal);.       
127c0 20 69 66 28 20 78 28 70 43 74 78 2c 20 69 42 6c   if( x(pCtx, iBl
127d0 6b 2c 20 69 53 6e 61 70 29 20 29 20 62 72 65 61  k, iSnap) ) brea
127e0 6b 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  k;.        rc = 
127f0 6d 75 6c 74 69 43 75 72 73 6f 72 41 64 76 61 6e  multiCursorAdvan
12800 63 65 28 70 43 73 72 2c 20 21 62 52 65 76 65 72  ce(pCsr, !bRever
12810 73 65 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  se);.      }.   
12820 20 7d 0a 20 20 7d 0a 0a 20 20 6c 73 6d 4d 43 75   }.  }..  lsmMCu
12830 72 73 6f 72 43 6c 6f 73 65 28 70 43 73 72 2c 20  rsorClose(pCsr, 
12840 30 29 3b 0a 20 20 69 66 28 20 70 53 6e 61 70 21  0);.  if( pSnap!
12850 3d 70 44 62 2d 3e 70 57 6f 72 6b 65 72 20 29 7b  =pDb->pWorker ){
12860 0a 20 20 20 20 6c 73 6d 46 72 65 65 53 6e 61 70  .    lsmFreeSnap
12870 73 68 6f 74 28 70 44 62 2d 3e 70 45 6e 76 2c 20  shot(pDb->pEnv, 
12880 70 53 6e 61 70 29 3b 0a 20 20 7d 0a 0a 20 20 72  pSnap);.  }..  r
12890 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74  eturn rc;.}..int
128a0 20 6c 73 6d 53 6f 72 74 65 64 4c 6f 61 64 46 72   lsmSortedLoadFr
128b0 65 65 6c 69 73 74 28 0a 20 20 6c 73 6d 5f 64 62  eelist(.  lsm_db
128c0 20 2a 70 44 62 2c 20 20 20 20 20 20 20 20 20 20   *pDb,          
128d0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
128e0 61 62 61 73 65 20 68 61 6e 64 6c 65 20 28 6d 75  abase handle (mu
128f0 73 74 20 62 65 20 77 6f 72 6b 65 72 29 20 2a 2f  st be worker) */
12900 0a 20 20 76 6f 69 64 20 2a 2a 70 70 56 61 6c 2c  .  void **ppVal,
12910 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12920 20 20 20 2f 2a 20 4f 55 54 3a 20 42 6c 6f 62 20     /* OUT: Blob 
12930 63 6f 6e 74 61 69 6e 69 6e 67 20 4c 53 4d 20 66  containing LSM f
12940 72 65 65 2d 6c 69 73 74 20 2a 2f 0a 20 20 69 6e  ree-list */.  in
12950 74 20 2a 70 6e 56 61 6c 20 20 20 20 20 20 20 20  t *pnVal        
12960 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
12970 20 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 2a 70   OUT: Size of *p
12980 70 56 61 6c 20 62 6c 6f 62 20 69 6e 20 62 79 74  pVal blob in byt
12990 65 73 20 2a 2f 0a 29 7b 0a 20 20 4d 75 6c 74 69  es */.){.  Multi
129a0 43 75 72 73 6f 72 20 2a 70 43 73 72 3b 20 20 20  Cursor *pCsr;   
129b0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
129c0 72 73 6f 72 20 75 73 65 64 20 74 6f 20 72 65 74  rsor used to ret
129d0 72 65 69 76 65 20 66 72 65 65 2d 6c 69 73 74 20  reive free-list 
129e0 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53  */.  int rc = LS
129f0 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  M_OK;           
12a00 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43       /* Return C
12a10 6f 64 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  ode */..  assert
12a20 28 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 20 29  ( pDb->pWorker )
12a30 3b 0a 20 20 61 73 73 65 72 74 28 20 2a 70 70 56  ;.  assert( *ppV
12a40 61 6c 3d 3d 30 20 26 26 20 2a 70 6e 56 61 6c 3d  al==0 && *pnVal=
12a50 3d 30 20 29 3b 0a 0a 20 20 70 43 73 72 20 3d 20  =0 );..  pCsr = 
12a60 6d 75 6c 74 69 43 75 72 73 6f 72 4e 65 77 28 70  multiCursorNew(p
12a70 44 62 2c 20 26 72 63 29 3b 0a 20 20 69 66 28 20  Db, &rc);.  if( 
12a80 70 43 73 72 20 29 7b 0a 20 20 20 20 72 63 20 3d  pCsr ){.    rc =
12a90 20 6d 75 6c 74 69 43 75 72 73 6f 72 41 64 64 41   multiCursorAddA
12aa0 6c 6c 28 70 43 73 72 2c 20 70 44 62 2d 3e 70 57  ll(pCsr, pDb->pW
12ab0 6f 72 6b 65 72 29 3b 0a 20 20 20 20 70 43 73 72  orker);.    pCsr
12ac0 2d 3e 66 6c 61 67 73 20 7c 3d 20 43 55 52 53 4f  ->flags |= CURSO
12ad0 52 5f 49 47 4e 4f 52 45 5f 44 45 4c 45 54 45 3b  R_IGNORE_DELETE;
12ae0 0a 20 20 7d 0a 20 20 0a 20 20 69 66 28 20 72 63  .  }.  .  if( rc
12af0 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20  ==LSM_OK ){.    
12b00 72 63 20 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 4c  rc = lsmMCursorL
12b10 61 73 74 28 70 43 73 72 29 3b 0a 20 20 20 20 69  ast(pCsr);.    i
12b20 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 0a 20  f( rc==LSM_OK . 
12b30 20 20 20 20 26 26 20 72 74 49 73 57 72 69 74 65      && rtIsWrite
12b40 28 70 43 73 72 2d 3e 65 54 79 70 65 29 20 26 26  (pCsr->eType) &&
12b50 20 72 74 49 73 53 79 73 74 65 6d 28 70 43 73 72   rtIsSystem(pCsr
12b60 2d 3e 65 54 79 70 65 29 0a 20 20 20 20 20 26 26  ->eType).     &&
12b70 20 70 43 73 72 2d 3e 6b 65 79 2e 6e 44 61 74 61   pCsr->key.nData
12b80 3d 3d 38 20 0a 20 20 20 20 20 26 26 20 30 3d 3d  ==8 .     && 0==
12b90 6d 65 6d 63 6d 70 28 70 43 73 72 2d 3e 6b 65 79  memcmp(pCsr->key
12ba0 2e 70 44 61 74 61 2c 20 22 46 52 45 45 4c 49 53  .pData, "FREELIS
12bb0 54 22 2c 20 38 29 0a 20 20 20 20 29 7b 0a 20 20  T", 8).    ){.  
12bc0 20 20 20 20 76 6f 69 64 20 2a 70 56 61 6c 3b 20      void *pVal; 
12bd0 69 6e 74 20 6e 56 61 6c 3b 20 20 20 20 20 20 20  int nVal;       
12be0 20 20 2f 2a 20 56 61 6c 75 65 20 72 65 61 64 20    /* Value read 
12bf0 66 72 6f 6d 20 64 61 74 61 62 61 73 65 20 2a 2f  from database */
12c00 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 4d  .      rc = lsmM
12c10 43 75 72 73 6f 72 56 61 6c 75 65 28 70 43 73 72  CursorValue(pCsr
12c20 2c 20 26 70 56 61 6c 2c 20 26 6e 56 61 6c 29 3b  , &pVal, &nVal);
12c30 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  .      if( rc==L
12c40 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  SM_OK ){.       
12c50 20 2a 70 70 56 61 6c 20 3d 20 6c 73 6d 4d 61 6c   *ppVal = lsmMal
12c60 6c 6f 63 52 63 28 70 44 62 2d 3e 70 45 6e 76 2c  locRc(pDb->pEnv,
12c70 20 6e 56 61 6c 2c 20 26 72 63 29 3b 0a 20 20 20   nVal, &rc);.   
12c80 20 20 20 20 20 69 66 28 20 2a 70 70 56 61 6c 20       if( *ppVal 
12c90 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d  ){.          mem
12ca0 63 70 79 28 2a 70 70 56 61 6c 2c 20 70 56 61 6c  cpy(*ppVal, pVal
12cb0 2c 20 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 20  , nVal);.       
12cc0 20 20 20 2a 70 6e 56 61 6c 20 3d 20 6e 56 61 6c     *pnVal = nVal
12cd0 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
12ce0 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 6c    }.    }..    l
12cf0 73 6d 4d 43 75 72 73 6f 72 43 6c 6f 73 65 28 70  smMCursorClose(p
12d00 43 73 72 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20 20  Csr, 0);.  }..  
12d10 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
12d20 61 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 43 75  atic int multiCu
12d30 72 73 6f 72 41 6c 6c 6f 63 54 72 65 65 28 4d 75  rsorAllocTree(Mu
12d40 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 29  ltiCursor *pCsr)
12d50 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d  {.  int rc = LSM
12d60 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 43 73 72 2d  _OK;.  if( pCsr-
12d70 3e 61 54 72 65 65 3d 3d 30 20 29 7b 0a 20 20 20  >aTree==0 ){.   
12d80 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20   int nByte;     
12d90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
12da0 2a 20 42 79 74 65 73 20 6f 66 20 73 70 61 63 65  * Bytes of space
12db0 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a   to allocate */.
12dc0 20 20 20 20 69 6e 74 20 6e 4d 69 6e 3b 20 20 20      int nMin;   
12dd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12de0 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65    /* Total numbe
12df0 72 20 6f 66 20 63 75 72 73 6f 72 73 20 62 65 69  r of cursors bei
12e00 6e 67 20 6d 65 72 67 65 64 20 2a 2f 0a 0a 20 20  ng merged */..  
12e10 20 20 6e 4d 69 6e 20 3d 20 43 55 52 53 4f 52 5f    nMin = CURSOR_
12e20 44 41 54 41 5f 53 45 47 4d 45 4e 54 20 2b 20 70  DATA_SEGMENT + p
12e30 43 73 72 2d 3e 6e 50 74 72 20 2b 20 28 70 43 73  Csr->nPtr + (pCs
12e40 72 2d 3e 70 42 74 43 73 72 21 3d 30 29 3b 0a 20  r->pBtCsr!=0);. 
12e50 20 20 20 70 43 73 72 2d 3e 6e 54 72 65 65 20 3d     pCsr->nTree =
12e60 20 32 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 70   2;.    while( p
12e70 43 73 72 2d 3e 6e 54 72 65 65 3c 6e 4d 69 6e 20  Csr->nTree<nMin 
12e80 29 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 6e  ){.      pCsr->n
12e90 54 72 65 65 20 3d 20 70 43 73 72 2d 3e 6e 54 72  Tree = pCsr->nTr
12ea0 65 65 2a 32 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  ee*2;.    }..   
12eb0 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
12ec0 69 6e 74 29 2a 70 43 73 72 2d 3e 6e 54 72 65 65  int)*pCsr->nTree
12ed0 2a 32 3b 0a 20 20 20 20 70 43 73 72 2d 3e 61 54  *2;.    pCsr->aT
12ee0 72 65 65 20 3d 20 28 69 6e 74 20 2a 29 6c 73 6d  ree = (int *)lsm
12ef0 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28 70 43 73  MallocZeroRc(pCs
12f00 72 2d 3e 70 44 62 2d 3e 70 45 6e 76 2c 20 6e 42  r->pDb->pEnv, nB
12f10 79 74 65 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 20  yte, &rc);.  }. 
12f20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
12f30 74 61 74 69 63 20 76 6f 69 64 20 6d 75 6c 74 69  tatic void multi
12f40 43 75 72 73 6f 72 43 61 63 68 65 4b 65 79 28 4d  CursorCacheKey(M
12f50 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72  ultiCursor *pCsr
12f60 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 69  , int *pRc){.  i
12f70 66 28 20 2a 70 52 63 3d 3d 4c 53 4d 5f 4f 4b 20  f( *pRc==LSM_OK 
12f80 29 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 4b 65  ){.    void *pKe
12f90 79 3b 0a 20 20 20 20 69 6e 74 20 6e 4b 65 79 3b  y;.    int nKey;
12fa0 0a 20 20 20 20 6d 75 6c 74 69 43 75 72 73 6f 72  .    multiCursor
12fb0 47 65 74 4b 65 79 28 70 43 73 72 2c 20 70 43 73  GetKey(pCsr, pCs
12fc0 72 2d 3e 61 54 72 65 65 5b 31 5d 2c 20 26 70 43  r->aTree[1], &pC
12fd0 73 72 2d 3e 65 54 79 70 65 2c 20 26 70 4b 65 79  sr->eType, &pKey
12fe0 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 20 20 2a 70  , &nKey);.    *p
12ff0 52 63 20 3d 20 73 6f 72 74 65 64 42 6c 6f 62 53  Rc = sortedBlobS
13000 65 74 28 70 43 73 72 2d 3e 70 44 62 2d 3e 70 45  et(pCsr->pDb->pE
13010 6e 76 2c 20 26 70 43 73 72 2d 3e 6b 65 79 2c 20  nv, &pCsr->key, 
13020 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 20 20 7d  pKey, nKey);.  }
13030 0a 7d 0a 0a 23 69 66 64 65 66 20 4c 53 4d 5f 44  .}..#ifdef LSM_D
13040 45 42 55 47 5f 45 58 50 45 4e 53 49 56 45 0a 73  EBUG_EXPENSIVE.s
13050 74 61 74 69 63 20 76 6f 69 64 20 61 73 73 65 72  tatic void asser
13060 74 43 75 72 73 6f 72 54 72 65 65 28 4d 75 6c 74  tCursorTree(Mult
13070 69 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a  iCursor *pCsr){.
13080 20 20 69 6e 74 20 62 52 65 76 20 3d 20 21 21 28    int bRev = !!(
13090 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20 43 55  pCsr->flags & CU
130a0 52 53 4f 52 5f 50 52 45 56 5f 4f 4b 29 3b 0a 20  RSOR_PREV_OK);. 
130b0 20 69 6e 74 20 2a 61 53 61 76 65 20 3d 20 70 43   int *aSave = pC
130c0 73 72 2d 3e 61 54 72 65 65 3b 0a 20 20 69 6e 74  sr->aTree;.  int
130d0 20 6e 53 61 76 65 20 3d 20 70 43 73 72 2d 3e 6e   nSave = pCsr->n
130e0 54 72 65 65 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  Tree;.  int rc;.
130f0 0a 20 20 70 43 73 72 2d 3e 61 54 72 65 65 20 3d  .  pCsr->aTree =
13100 20 30 3b 0a 20 20 70 43 73 72 2d 3e 6e 54 72 65   0;.  pCsr->nTre
13110 65 20 3d 20 30 3b 0a 20 20 72 63 20 3d 20 6d 75  e = 0;.  rc = mu
13120 6c 74 69 43 75 72 73 6f 72 41 6c 6c 6f 63 54 72  ltiCursorAllocTr
13130 65 65 28 70 43 73 72 29 3b 0a 20 20 69 66 28 20  ee(pCsr);.  if( 
13140 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20  rc==LSM_OK ){.  
13150 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72    int i;.    for
13160 28 69 3d 70 43 73 72 2d 3e 6e 54 72 65 65 2d 31  (i=pCsr->nTree-1
13170 3b 20 69 3e 30 3b 20 69 2d 2d 29 7b 0a 20 20 20  ; i>0; i--){.   
13180 20 20 20 6d 75 6c 74 69 43 75 72 73 6f 72 44 6f     multiCursorDo
13190 43 6f 6d 70 61 72 65 28 70 43 73 72 2c 20 69 2c  Compare(pCsr, i,
131a0 20 62 52 65 76 29 3b 0a 20 20 20 20 7d 0a 0a 20   bRev);.    }.. 
131b0 20 20 20 61 73 73 65 72 74 28 20 6e 53 61 76 65     assert( nSave
131c0 3d 3d 70 43 73 72 2d 3e 6e 54 72 65 65 20 0a 20  ==pCsr->nTree . 
131d0 20 20 20 20 20 20 20 26 26 20 30 3d 3d 6d 65 6d         && 0==mem
131e0 63 6d 70 28 61 53 61 76 65 2c 20 70 43 73 72 2d  cmp(aSave, pCsr-
131f0 3e 61 54 72 65 65 2c 20 73 69 7a 65 6f 66 28 69  >aTree, sizeof(i
13200 6e 74 29 2a 6e 53 61 76 65 29 0a 20 20 20 20 29  nt)*nSave).    )
13210 3b 0a 0a 20 20 20 20 6c 73 6d 46 72 65 65 28 70  ;..    lsmFree(p
13220 43 73 72 2d 3e 70 44 62 2d 3e 70 45 6e 76 2c 20  Csr->pDb->pEnv, 
13230 70 43 73 72 2d 3e 61 54 72 65 65 29 3b 0a 20 20  pCsr->aTree);.  
13240 7d 0a 0a 20 20 70 43 73 72 2d 3e 61 54 72 65 65  }..  pCsr->aTree
13250 20 3d 20 61 53 61 76 65 3b 0a 20 20 70 43 73 72   = aSave;.  pCsr
13260 2d 3e 6e 54 72 65 65 20 3d 20 6e 53 61 76 65 3b  ->nTree = nSave;
13270 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66 69 6e  .}.#else.# defin
13280 65 20 61 73 73 65 72 74 43 75 72 73 6f 72 54 72  e assertCursorTr
13290 65 65 28 78 29 0a 23 65 6e 64 69 66 0a 0a 73 74  ee(x).#endif..st
132a0 61 74 69 63 20 69 6e 74 20 6d 63 75 72 73 6f 72  atic int mcursor
132b0 4c 6f 63 61 74 69 6f 6e 4f 6b 28 4d 75 6c 74 69  LocationOk(Multi
132c0 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e  Cursor *pCsr, in
132d0 74 20 62 44 65 6c 65 74 65 4f 6b 29 7b 0a 20 20  t bDeleteOk){.  
132e0 69 6e 74 20 65 54 79 70 65 20 3d 20 70 43 73 72  int eType = pCsr
132f0 2d 3e 65 54 79 70 65 3b 0a 20 20 69 6e 74 20 69  ->eType;.  int i
13300 4b 65 79 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  Key;.  int i;.  
13310 69 6e 74 20 72 64 6d 61 73 6b 3b 0a 20 20 0a 20  int rdmask;.  . 
13320 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e 66   assert( pCsr->f
13330 6c 61 67 73 20 26 20 28 43 55 52 53 4f 52 5f 4e  lags & (CURSOR_N
13340 45 58 54 5f 4f 4b 7c 43 55 52 53 4f 52 5f 50 52  EXT_OK|CURSOR_PR
13350 45 56 5f 4f 4b 29 20 29 3b 0a 20 20 61 73 73 65  EV_OK) );.  asse
13360 72 74 43 75 72 73 6f 72 54 72 65 65 28 70 43 73  rtCursorTree(pCs
13370 72 29 3b 0a 0a 20 20 72 64 6d 61 73 6b 20 3d 20  r);..  rdmask = 
13380 28 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20 43  (pCsr->flags & C
13390 55 52 53 4f 52 5f 4e 45 58 54 5f 4f 4b 29 20 3f  URSOR_NEXT_OK) ?
133a0 20 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45 54 45 20   LSM_END_DELETE 
133b0 3a 20 4c 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45  : LSM_START_DELE
133c0 54 45 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65  TE;..  /* If the
133d0 20 63 75 72 73 6f 72 20 64 6f 65 73 20 6e 6f 74   cursor does not
133e0 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74   currently point
133f0 20 74 6f 20 61 6e 20 61 63 74 75 61 6c 20 64 61   to an actual da
13400 74 61 62 61 73 65 20 6b 65 79 20 28 69 2e 65 2e  tabase key (i.e.
13410 0a 20 20 2a 2a 20 69 74 20 70 6f 69 6e 74 73 20  .  ** it points 
13420 74 6f 20 61 20 64 65 6c 65 74 65 20 6b 65 79 2c  to a delete key,
13430 20 6f 72 20 74 68 65 20 73 74 61 72 74 20 6f 72   or the start or
13440 20 65 6e 64 20 6f 66 20 61 20 72 61 6e 67 65 2d   end of a range-
13450 64 65 6c 65 74 65 29 2c 20 61 6e 64 0a 20 20 2a  delete), and.  *
13460 2a 20 74 68 65 20 43 55 52 53 4f 52 5f 49 47 4e  * the CURSOR_IGN
13470 4f 52 45 5f 44 45 4c 45 54 45 20 66 6c 61 67 20  ORE_DELETE flag 
13480 69 73 20 73 65 74 2c 20 73 6b 69 70 20 70 61 73  is set, skip pas
13490 74 20 74 68 69 73 20 65 6e 74 72 79 2e 20 20 2a  t this entry.  *
134a0 2f 0a 20 20 69 66 28 20 28 70 43 73 72 2d 3e 66  /.  if( (pCsr->f
134b0 6c 61 67 73 20 26 20 43 55 52 53 4f 52 5f 49 47  lags & CURSOR_IG
134c0 4e 4f 52 45 5f 44 45 4c 45 54 45 29 20 26 26 20  NORE_DELETE) && 
134d0 62 44 65 6c 65 74 65 4f 6b 3d 3d 30 20 29 7b 0a  bDeleteOk==0 ){.
134e0 20 20 20 20 69 66 28 20 28 65 54 79 70 65 20 26      if( (eType &
134f0 20 4c 53 4d 5f 49 4e 53 45 52 54 29 3d 3d 30 20   LSM_INSERT)==0 
13500 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a  ) return 0;.  }.
13510 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 63 75 72  .  /* If the cur
13520 73 6f 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20  sor points to a 
13530 73 79 73 74 65 6d 20 6b 65 79 20 28 66 72 65 65  system key (free
13540 2d 6c 69 73 74 20 65 6e 74 72 79 29 2c 20 61 6e  -list entry), an
13550 64 20 74 68 65 0a 20 20 2a 2a 20 43 55 52 53 4f  d the.  ** CURSO
13560 52 5f 49 47 4e 4f 52 45 5f 53 59 53 54 45 4d 20  R_IGNORE_SYSTEM 
13570 66 6c 61 67 20 69 73 20 73 65 74 2c 20 73 6b 69  flag is set, ski
13580 70 20 74 68 69 65 20 65 6e 74 72 79 2e 20 20 2a  p thie entry.  *
13590 2f 0a 20 20 69 66 28 20 28 70 43 73 72 2d 3e 66  /.  if( (pCsr->f
135a0 6c 61 67 73 20 26 20 43 55 52 53 4f 52 5f 49 47  lags & CURSOR_IG
135b0 4e 4f 52 45 5f 53 59 53 54 45 4d 29 20 26 26 20  NORE_SYSTEM) && 
135c0 72 74 54 6f 70 69 63 28 65 54 79 70 65 29 21 3d  rtTopic(eType)!=
135d0 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  0 ){.    return 
135e0 30 3b 0a 20 20 7d 0a 0a 23 69 66 6e 64 65 66 20  0;.  }..#ifndef 
135f0 4e 44 45 42 55 47 0a 20 20 2f 2a 20 54 68 69 73  NDEBUG.  /* This
13600 20 62 6c 6f 63 6b 20 66 69 72 65 73 20 61 73 73   block fires ass
13610 65 72 74 28 29 20 73 74 61 74 65 6d 65 6e 74 73  ert() statements
13620 20 74 6f 20 63 68 65 63 6b 20 6f 6e 65 20 6f 66   to check one of
13630 20 74 68 65 20 61 73 73 75 6d 70 74 69 6f 6e 73   the assumptions
13640 0a 20 20 2a 2a 20 69 6e 20 74 68 65 20 63 6f 6d  .  ** in the com
13650 6d 65 6e 74 20 62 65 6c 6f 77 20 2d 20 74 68 61  ment below - tha
13660 74 20 69 66 20 74 68 65 20 6c 68 73 20 73 75 62  t if the lhs sub
13670 2d 63 75 72 73 6f 72 20 6f 66 20 61 20 6c 65 76  -cursor of a lev
13680 65 6c 20 75 6e 64 65 72 67 6f 69 6e 67 0a 20 20  el undergoing.  
13690 2a 2a 20 61 20 6d 65 72 67 65 20 69 73 20 76 61  ** a merge is va
136a0 6c 69 64 2c 20 74 68 65 6e 20 61 6c 6c 20 74 68  lid, then all th
136b0 65 20 72 68 73 20 73 75 62 2d 63 75 72 73 6f 72  e rhs sub-cursor
136c0 73 20 6d 75 73 74 20 62 65 20 61 74 20 45 4f 46  s must be at EOF
136d0 2e 20 0a 20 20 2a 2a 0a 20 20 2a 2a 20 41 6c 73  . .  **.  ** Als
136e0 6f 20 61 73 73 65 72 74 20 74 68 61 74 20 61 6c  o assert that al
136f0 6c 20 72 68 73 20 73 75 62 2d 63 75 72 73 6f 72  l rhs sub-cursor
13700 73 20 61 72 65 20 65 69 74 68 65 72 20 61 74 20  s are either at 
13710 45 4f 46 20 6f 72 20 70 6f 69 6e 74 20 74 6f 0a  EOF or point to.
13720 20 20 2a 2a 20 61 20 6b 65 79 20 74 68 61 74 20    ** a key that 
13730 69 73 20 6e 6f 74 20 6c 65 73 73 20 74 68 61 6e  is not less than
13740 20 74 68 65 20 6c 65 76 65 6c 20 73 70 6c 69 74   the level split
13750 2d 6b 65 79 2e 20 20 2a 2f 0a 20 20 66 6f 72 28  -key.  */.  for(
13760 69 3d 30 3b 20 69 3c 70 43 73 72 2d 3e 6e 50 74  i=0; i<pCsr->nPt
13770 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 53 65 67  r; i++){.    Seg
13780 6d 65 6e 74 50 74 72 20 2a 70 50 74 72 20 3d 20  mentPtr *pPtr = 
13790 26 70 43 73 72 2d 3e 61 50 74 72 5b 69 5d 3b 0a  &pCsr->aPtr[i];.
137a0 20 20 20 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 20      Level *pLvl 
137b0 3d 20 70 50 74 72 2d 3e 70 4c 65 76 65 6c 3b 0a  = pPtr->pLevel;.
137c0 20 20 20 20 69 66 28 20 70 4c 76 6c 2d 3e 6e 52      if( pLvl->nR
137d0 69 67 68 74 20 26 26 20 70 50 74 72 2d 3e 70 50  ight && pPtr->pP
137e0 67 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70  g ){.      if( p
137f0 50 74 72 2d 3e 70 53 65 67 3d 3d 26 70 4c 76 6c  Ptr->pSeg==&pLvl
13800 2d 3e 6c 68 73 20 29 7b 0a 20 20 20 20 20 20 20  ->lhs ){.       
13810 20 69 6e 74 20 6a 3b 0a 20 20 20 20 20 20 20 20   int j;.        
13820 66 6f 72 28 6a 3d 30 3b 20 6a 3c 70 4c 76 6c 2d  for(j=0; j<pLvl-
13830 3e 6e 52 69 67 68 74 3b 20 6a 2b 2b 29 20 61 73  >nRight; j++) as
13840 73 65 72 74 28 20 70 50 74 72 5b 6a 2b 31 5d 2e  sert( pPtr[j+1].
13850 70 50 67 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20  pPg==0 );.      
13860 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69  }else{.        i
13870 6e 74 20 72 65 73 20 3d 20 73 6f 72 74 65 64 4b  nt res = sortedK
13880 65 79 43 6f 6d 70 61 72 65 28 70 43 73 72 2d 3e  eyCompare(pCsr->
13890 70 44 62 2d 3e 78 43 6d 70 2c 20 0a 20 20 20 20  pDb->xCmp, .    
138a0 20 20 20 20 20 20 20 20 72 74 54 6f 70 69 63 28          rtTopic(
138b0 70 50 74 72 2d 3e 65 54 79 70 65 29 2c 20 70 50  pPtr->eType), pP
138c0 74 72 2d 3e 70 4b 65 79 2c 20 70 50 74 72 2d 3e  tr->pKey, pPtr->
138d0 6e 4b 65 79 2c 0a 20 20 20 20 20 20 20 20 20 20  nKey,.          
138e0 20 20 70 4c 76 6c 2d 3e 69 53 70 6c 69 74 54 6f    pLvl->iSplitTo
138f0 70 69 63 2c 20 70 4c 76 6c 2d 3e 70 53 70 6c 69  pic, pLvl->pSpli
13900 74 4b 65 79 2c 20 70 4c 76 6c 2d 3e 6e 53 70 6c  tKey, pLvl->nSpl
13910 69 74 4b 65 79 0a 20 20 20 20 20 20 20 20 29 3b  itKey.        );
13920 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28  .        assert(
13930 20 72 65 73 3e 3d 30 20 29 3b 0a 20 20 20 20 20   res>=0 );.     
13940 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 23 65 6e   }.    }.  }.#en
13950 64 69 66 0a 0a 20 20 2f 2a 20 4e 6f 77 20 63 68  dif..  /* Now ch
13960 65 63 6b 20 69 66 20 74 68 69 73 20 6b 65 79 20  eck if this key 
13970 68 61 73 20 61 6c 72 65 61 64 79 20 62 65 65 6e  has already been
13980 20 64 65 6c 65 74 65 64 20 62 79 20 61 20 72 61   deleted by a ra
13990 6e 67 65 2d 64 65 6c 65 74 65 2e 20 49 66 20 0a  nge-delete. If .
139a0 20 20 2a 2a 20 73 6f 2c 20 73 6b 69 70 20 70 61    ** so, skip pa
139b0 73 74 20 69 74 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  st it..  **.  **
139c0 20 41 73 73 75 6d 65 2c 20 66 6f 72 20 74 68 65   Assume, for the
139d0 20 6d 6f 6d 65 6e 74 2c 20 74 68 61 74 20 74 68   moment, that th
139e0 65 20 74 72 65 65 20 63 6f 6e 74 61 69 6e 73 20  e tree contains 
139f0 6e 6f 20 6c 65 76 65 6c 73 20 63 75 72 72 65 6e  no levels curren
13a00 74 6c 79 20 0a 20 20 2a 2a 20 75 6e 64 65 72 67  tly .  ** underg
13a10 6f 69 6e 67 20 69 6e 63 72 65 6d 65 6e 74 61 6c  oing incremental
13a20 20 6d 65 72 67 65 2c 20 61 6e 64 20 74 68 61 74   merge, and that
13a30 20 74 68 69 73 20 63 75 72 73 6f 72 20 69 73 20   this cursor is 
13a40 69 74 65 72 61 74 69 6e 67 20 66 6f 72 77 61 72  iterating forwar
13a50 64 73 0a 20 20 2a 2a 20 74 68 72 6f 75 67 68 20  ds.  ** through 
13a60 74 68 65 20 64 61 74 61 62 61 73 65 20 6b 65 79  the database key
13a70 73 2e 20 54 68 65 20 63 75 72 73 6f 72 20 63 75  s. The cursor cu
13a80 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74  rrently points t
13a90 6f 20 61 20 6b 65 79 20 69 6e 0a 20 20 2a 2a 20  o a key in.  ** 
13aa0 6c 65 76 65 6c 20 4c 2e 20 54 68 69 73 20 6b 65  level L. This ke
13ab0 79 20 68 61 73 20 61 6c 72 65 61 64 79 20 62 65  y has already be
13ac0 65 6e 20 64 65 6c 65 74 65 64 20 69 66 20 61 6e  en deleted if an
13ad0 79 20 6f 66 20 74 68 65 20 73 75 62 2d 63 75 72  y of the sub-cur
13ae0 73 6f 72 73 0a 20 20 2a 2a 20 74 68 61 74 20 70  sors.  ** that p
13af0 6f 69 6e 74 20 74 6f 20 6c 65 76 65 6c 73 20 6e  oint to levels n
13b00 65 77 65 72 20 74 68 61 6e 20 4c 20 28 6f 72 20  ewer than L (or 
13b10 74 6f 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79  to the in-memory
13b20 20 74 72 65 65 29 20 70 6f 69 6e 74 20 74 6f 0a   tree) point to.
13b30 20 20 2a 2a 20 61 20 6b 65 79 20 67 72 65 61 74    ** a key great
13b40 65 72 20 74 68 61 6e 20 74 68 65 20 63 75 72 72  er than the curr
13b50 65 6e 74 20 6b 65 79 20 77 69 74 68 20 74 68 65  ent key with the
13b60 20 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45 54 45 20   LSM_END_DELETE 
13b70 66 6c 61 67 20 73 65 74 2e 0a 20 20 2a 2a 0a 20  flag set..  **. 
13b80 20 2a 2a 20 4f 72 2c 20 69 66 20 74 68 65 20 63   ** Or, if the c
13b90 75 72 73 6f 72 20 69 73 20 69 74 65 72 61 74 69  ursor is iterati
13ba0 6e 67 20 62 61 63 6b 77 61 72 64 73 20 74 68 72  ng backwards thr
13bb0 6f 75 67 68 20 64 61 74 61 20 6b 65 79 73 2c 20  ough data keys, 
13bc0 69 66 20 61 6e 79 0a 20 20 2a 2a 20 73 75 63 68  if any.  ** such
13bd0 20 73 75 62 2d 63 75 72 73 6f 72 20 70 6f 69 6e   sub-cursor poin
13be0 74 73 20 74 6f 20 61 20 6b 65 79 20 73 6d 61 6c  ts to a key smal
13bf0 6c 65 72 20 74 68 61 6e 20 74 68 65 20 63 75 72  ler than the cur
13c00 72 65 6e 74 20 6b 65 79 20 77 69 74 68 20 74 68  rent key with th
13c10 65 0a 20 20 2a 2a 20 4c 53 4d 5f 53 54 41 52 54  e.  ** LSM_START
13c20 5f 44 45 4c 45 54 45 20 66 6c 61 67 20 73 65 74  _DELETE flag set
13c30 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 57 68 79 20  ..  **.  ** Why 
13c40 69 74 20 77 6f 72 6b 73 20 77 69 74 68 20 6c 65  it works with le
13c50 76 65 6c 73 20 75 6e 64 65 72 67 6f 69 6e 67 20  vels undergoing 
13c60 61 20 6d 65 72 67 65 20 74 6f 6f 3a 0a 20 20 2a  a merge too:.  *
13c70 2a 0a 20 20 2a 2a 20 57 68 65 6e 20 61 20 63 75  *.  ** When a cu
13c80 72 73 6f 72 20 69 74 65 72 61 74 65 73 20 66 6f  rsor iterates fo
13c90 72 77 61 72 64 73 2c 20 74 68 65 20 73 75 62 2d  rwards, the sub-
13ca0 63 75 72 73 6f 72 73 20 66 6f 72 20 74 68 65 20  cursors for the 
13cb0 72 68 73 20 6f 66 20 61 20 0a 20 20 2a 2a 20 6c  rhs of a .  ** l
13cc0 65 76 65 6c 20 61 72 65 20 6f 6e 6c 79 20 61 63  evel are only ac
13cd0 74 69 76 61 74 65 64 20 6f 6e 63 65 20 74 68 65  tivated once the
13ce0 20 6c 68 73 20 72 65 61 63 68 65 73 20 45 4f 46   lhs reaches EOF
13cf0 2e 20 53 6f 20 77 68 65 6e 20 69 74 65 72 61 74  . So when iterat
13d00 69 6e 67 0a 20 20 2a 2a 20 66 6f 72 77 61 72 64  ing.  ** forward
13d10 73 2c 20 74 68 65 20 6b 65 79 73 20 76 69 73 69  s, the keys visi
13d20 74 65 64 20 61 72 65 20 74 68 65 20 73 61 6d 65  ted are the same
13d30 20 61 73 20 69 66 20 74 68 65 20 6c 65 76 65 6c   as if the level
13d40 20 77 61 73 20 63 6f 6d 70 6c 65 74 65 6c 79 0a   was completely.
13d50 20 20 2a 2a 20 6d 65 72 67 65 64 2e 0a 20 20 2a    ** merged..  *
13d60 2a 0a 20 20 2a 2a 20 49 66 20 74 68 65 20 63 75  *.  ** If the cu
13d70 72 73 6f 72 20 69 73 20 69 74 65 72 61 74 69 6e  rsor is iteratin
13d80 67 20 62 61 63 6b 77 61 72 64 73 2c 20 74 68 65  g backwards, the
13d90 6e 20 74 68 65 20 6c 68 73 20 73 75 62 2d 63 75  n the lhs sub-cu
13da0 72 73 6f 72 20 69 73 20 6e 6f 74 20 0a 20 20 2a  rsor is not .  *
13db0 2a 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 75 6e  * initialized un
13dc0 74 69 6c 20 74 68 65 20 6c 61 73 74 20 6f 66 20  til the last of 
13dd0 74 68 65 20 72 68 73 20 73 75 62 2d 63 75 72 73  the rhs sub-curs
13de0 6f 72 73 20 68 61 73 20 72 65 61 63 68 65 64 20  ors has reached 
13df0 45 4f 46 2e 0a 20 20 2a 2a 20 41 64 64 69 74 69  EOF..  ** Additi
13e00 6f 6e 61 6c 6c 79 2c 20 69 66 20 74 68 65 20 53  onally, if the S
13e10 54 41 52 54 5f 44 45 4c 45 54 45 20 66 6c 61 67  TART_DELETE flag
13e20 20 69 73 20 73 65 74 20 6f 6e 20 74 68 65 20 6c   is set on the l
13e30 61 73 74 20 65 6e 74 72 79 20 28 69 6e 0a 20 20  ast entry (in.  
13e40 2a 2a 20 72 65 76 65 72 73 65 20 6f 72 64 65 72  ** reverse order
13e50 20 2d 20 73 6f 20 74 68 65 20 65 6e 74 72 79 20   - so the entry 
13e60 77 69 74 68 20 74 68 65 20 73 6d 61 6c 6c 65 73  with the smalles
13e70 74 20 6b 65 79 29 20 6f 66 20 61 20 72 68 73 20  t key) of a rhs 
13e80 73 75 62 2d 63 75 72 73 6f 72 2c 0a 20 20 2a 2a  sub-cursor,.  **
13e90 20 74 68 65 6e 20 61 20 70 73 65 75 64 6f 2d 6b   then a pseudo-k
13ea0 65 79 20 65 71 75 61 6c 20 74 6f 20 74 68 65 20  ey equal to the 
13eb0 6c 65 76 65 6c 73 20 73 70 6c 69 74 2d 6b 65 79  levels split-key
13ec0 20 77 69 74 68 20 74 68 65 20 45 4e 44 5f 44 45   with the END_DE
13ed0 4c 45 54 45 0a 20 20 2a 2a 20 66 6c 61 67 20 73  LETE.  ** flag s
13ee0 65 74 20 69 73 20 76 69 73 69 74 65 64 20 62 79  et is visited by
13ef0 20 74 68 65 20 73 75 62 2d 63 75 72 73 6f 72 2e   the sub-cursor.
13f00 0a 20 20 2a 2f 20 0a 20 20 69 4b 65 79 20 3d 20  .  */ .  iKey = 
13f10 70 43 73 72 2d 3e 61 54 72 65 65 5b 31 5d 3b 0a  pCsr->aTree[1];.
13f20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 69 4b 65    for(i=0; i<iKe
13f30 79 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74  y; i++){.    int
13f40 20 63 73 72 66 6c 61 67 73 3b 0a 20 20 20 20 6d   csrflags;.    m
13f50 75 6c 74 69 43 75 72 73 6f 72 47 65 74 4b 65 79  ultiCursorGetKey
13f60 28 70 43 73 72 2c 20 69 2c 20 26 63 73 72 66 6c  (pCsr, i, &csrfl
13f70 61 67 73 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20  ags, 0, 0);.    
13f80 69 66 28 20 28 72 64 6d 61 73 6b 20 26 20 63 73  if( (rdmask & cs
13f90 72 66 6c 61 67 73 29 20 29 7b 0a 20 20 20 20 20  rflags) ){.     
13fa0 20 63 6f 6e 73 74 20 69 6e 74 20 53 44 5f 45 44   const int SD_ED
13fb0 20 3d 20 28 4c 53 4d 5f 53 54 41 52 54 5f 44 45   = (LSM_START_DE
13fc0 4c 45 54 45 7c 4c 53 4d 5f 45 4e 44 5f 44 45 4c  LETE|LSM_END_DEL
13fd0 45 54 45 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ETE);.      if( 
13fe0 28 63 73 72 66 6c 61 67 73 20 26 20 53 44 5f 45  (csrflags & SD_E
13ff0 44 29 3d 3d 53 44 5f 45 44 20 0a 20 20 20 20 20  D)==SD_ED .     
14000 20 20 7c 7c 20 28 70 43 73 72 2d 3e 66 6c 61 67    || (pCsr->flag
14010 73 20 26 20 43 55 52 53 4f 52 5f 49 47 4e 4f 52  s & CURSOR_IGNOR
14020 45 5f 44 45 4c 45 54 45 29 3d 3d 30 0a 20 20 20  E_DELETE)==0.   
14030 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 76 6f     ){.        vo
14040 69 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b  id *pKey; int nK
14050 65 79 3b 0a 20 20 20 20 20 20 20 20 6d 75 6c 74  ey;.        mult
14060 69 43 75 72 73 6f 72 47 65 74 4b 65 79 28 70 43  iCursorGetKey(pC
14070 73 72 2c 20 69 2c 20 30 2c 20 26 70 4b 65 79 2c  sr, i, 0, &pKey,
14080 20 26 6e 4b 65 79 29 3b 0a 20 20 20 20 20 20 20   &nKey);.       
14090 20 69 66 28 20 30 3d 3d 73 6f 72 74 65 64 4b 65   if( 0==sortedKe
140a0 79 43 6f 6d 70 61 72 65 28 70 43 73 72 2d 3e 70  yCompare(pCsr->p
140b0 44 62 2d 3e 78 43 6d 70 2c 0a 20 20 20 20 20 20  Db->xCmp,.      
140c0 20 20 20 20 20 20 20 20 72 74 54 6f 70 69 63 28          rtTopic(
140d0 65 54 79 70 65 29 2c 20 70 43 73 72 2d 3e 6b 65  eType), pCsr->ke
140e0 79 2e 70 44 61 74 61 2c 20 70 43 73 72 2d 3e 6b  y.pData, pCsr->k
140f0 65 79 2e 6e 44 61 74 61 2c 0a 20 20 20 20 20 20  ey.nData,.      
14100 20 20 20 20 20 20 20 20 72 74 54 6f 70 69 63 28          rtTopic(
14110 63 73 72 66 6c 61 67 73 29 2c 20 70 4b 65 79 2c  csrflags), pKey,
14120 20 6e 4b 65 79 0a 20 20 20 20 20 20 20 20 29 29   nKey.        ))
14130 7b 0a 20 20 20 20 20 20 20 20 20 20 63 6f 6e 74  {.          cont
14140 69 6e 75 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a  inue;.        }.
14150 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 65        }.      re
14160 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 20 20  turn 0;.    }.  
14170 7d 0a 0a 20 20 2f 2a 20 54 68 65 20 63 75 72 72  }..  /* The curr
14180 65 6e 74 20 63 75 72 73 6f 72 20 70 6f 73 69 74  ent cursor posit
14190 69 6f 6e 20 69 73 20 6f 6e 65 20 74 68 69 73 20  ion is one this 
141a0 63 75 72 73 6f 72 20 73 68 6f 75 6c 64 20 76 69  cursor should vi
141b0 73 69 74 2e 20 52 65 74 75 72 6e 20 31 2e 20 2a  sit. Return 1. *
141c0 2f 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a  /.  return 1;.}.
141d0 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74  .static int mult
141e0 69 43 75 72 73 6f 72 53 65 74 75 70 54 72 65 65  iCursorSetupTree
141f0 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43  (MultiCursor *pC
14200 73 72 2c 20 69 6e 74 20 62 52 65 76 29 7b 0a 20  sr, int bRev){. 
14210 20 69 6e 74 20 72 63 3b 0a 0a 20 20 72 63 20 3d   int rc;..  rc =
14220 20 6d 75 6c 74 69 43 75 72 73 6f 72 41 6c 6c 6f   multiCursorAllo
14230 63 54 72 65 65 28 70 43 73 72 29 3b 0a 20 20 69  cTree(pCsr);.  i
14240 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b  f( rc==LSM_OK ){
14250 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
14260 66 6f 72 28 69 3d 70 43 73 72 2d 3e 6e 54 72 65  for(i=pCsr->nTre
14270 65 2d 31 3b 20 69 3e 30 3b 20 69 2d 2d 29 7b 0a  e-1; i>0; i--){.
14280 20 20 20 20 20 20 6d 75 6c 74 69 43 75 72 73 6f        multiCurso
14290 72 44 6f 43 6f 6d 70 61 72 65 28 70 43 73 72 2c  rDoCompare(pCsr,
142a0 20 69 2c 20 62 52 65 76 29 3b 0a 20 20 20 20 7d   i, bRev);.    }
142b0 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 43 75  .  }..  assertCu
142c0 72 73 6f 72 54 72 65 65 28 70 43 73 72 29 3b 0a  rsorTree(pCsr);.
142d0 20 20 6d 75 6c 74 69 43 75 72 73 6f 72 43 61 63    multiCursorCac
142e0 68 65 4b 65 79 28 70 43 73 72 2c 20 26 72 63 29  heKey(pCsr, &rc)
142f0 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d  ;..  if( rc==LSM
14300 5f 4f 4b 20 26 26 20 6d 63 75 72 73 6f 72 4c 6f  _OK && mcursorLo
14310 63 61 74 69 6f 6e 4f 6b 28 70 43 73 72 2c 20 30  cationOk(pCsr, 0
14320 29 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d  )==0 ){.    rc =
14330 20 6d 75 6c 74 69 43 75 72 73 6f 72 41 64 76 61   multiCursorAdva
14340 6e 63 65 28 70 43 73 72 2c 20 62 52 65 76 29 3b  nce(pCsr, bRev);
14350 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
14360 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74  ;.}...static int
14370 20 6d 75 6c 74 69 43 75 72 73 6f 72 45 6e 64 28   multiCursorEnd(
14380 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73  MultiCursor *pCs
14390 72 2c 20 69 6e 74 20 62 4c 61 73 74 29 7b 0a 20  r, int bLast){. 
143a0 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
143b0 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 70 43  ;.  int i;..  pC
143c0 73 72 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 28 43  sr->flags &= ~(C
143d0 55 52 53 4f 52 5f 4e 45 58 54 5f 4f 4b 20 7c 20  URSOR_NEXT_OK | 
143e0 43 55 52 53 4f 52 5f 50 52 45 56 5f 4f 4b 29 3b  CURSOR_PREV_OK);
143f0 0a 20 20 70 43 73 72 2d 3e 66 6c 61 67 73 20 7c  .  pCsr->flags |
14400 3d 20 28 62 4c 61 73 74 20 3f 20 43 55 52 53 4f  = (bLast ? CURSO
14410 52 5f 50 52 45 56 5f 4f 4b 20 3a 20 43 55 52 53  R_PREV_OK : CURS
14420 4f 52 5f 4e 45 58 54 5f 4f 4b 29 3b 0a 20 20 70  OR_NEXT_OK);.  p
14430 43 73 72 2d 3e 69 46 72 65 65 20 3d 20 30 3b 0a  Csr->iFree = 0;.
14440 0a 20 20 2f 2a 20 50 6f 73 69 74 69 6f 6e 20 74  .  /* Position t
14450 68 65 20 74 77 6f 20 69 6e 2d 6d 65 6d 6f 72 79  he two in-memory
14460 20 74 72 65 65 20 63 75 72 73 6f 72 73 20 2a 2f   tree cursors */
14470 0a 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d  .  for(i=0; rc==
14480 4c 53 4d 5f 4f 4b 20 26 26 20 69 3c 32 3b 20 69  LSM_OK && i<2; i
14490 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 70 43 73  ++){.    if( pCs
144a0 72 2d 3e 61 70 54 72 65 65 43 73 72 5b 69 5d 20  r->apTreeCsr[i] 
144b0 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 73  ){.      rc = ls
144c0 6d 54 72 65 65 43 75 72 73 6f 72 45 6e 64 28 70  mTreeCursorEnd(p
144d0 43 73 72 2d 3e 61 70 54 72 65 65 43 73 72 5b 69  Csr->apTreeCsr[i
144e0 5d 2c 20 62 4c 61 73 74 29 3b 0a 20 20 20 20 7d  ], bLast);.    }
144f0 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69 3d 30 3b  .  }..  for(i=0;
14500 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 69   rc==LSM_OK && i
14510 3c 70 43 73 72 2d 3e 6e 50 74 72 3b 20 69 2b 2b  <pCsr->nPtr; i++
14520 29 7b 0a 20 20 20 20 53 65 67 6d 65 6e 74 50 74  ){.    SegmentPt
14530 72 20 2a 70 50 74 72 20 3d 20 26 70 43 73 72 2d  r *pPtr = &pCsr-
14540 3e 61 50 74 72 5b 69 5d 3b 0a 20 20 20 20 4c 65  >aPtr[i];.    Le
14550 76 65 6c 20 2a 70 4c 76 6c 20 3d 20 70 50 74 72  vel *pLvl = pPtr
14560 2d 3e 70 4c 65 76 65 6c 3b 0a 20 20 20 20 69 6e  ->pLevel;.    in
14570 74 20 69 52 68 73 3b 0a 20 20 20 20 69 6e 74 20  t iRhs;.    int 
14580 62 48 69 74 20 3d 20 30 3b 0a 0a 20 20 20 20 69  bHit = 0;..    i
14590 66 28 20 62 4c 61 73 74 20 29 7b 0a 20 20 20 20  f( bLast ){.    
145a0 20 20 66 6f 72 28 69 52 68 73 3d 30 3b 20 69 52    for(iRhs=0; iR
145b0 68 73 3c 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 20  hs<pLvl->nRight 
145c0 26 26 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 3b 20 69  && rc==LSM_OK; i
145d0 52 68 73 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  Rhs++){.        
145e0 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74 72 45  rc = segmentPtrE
145f0 6e 64 28 70 43 73 72 2c 20 26 70 50 74 72 5b 69  nd(pCsr, &pPtr[i
14600 52 68 73 2b 31 5d 2c 20 31 29 3b 0a 20 20 20 20  Rhs+1], 1);.    
14610 20 20 20 20 69 66 28 20 70 50 74 72 5b 69 52 68      if( pPtr[iRh
14620 73 2b 31 5d 2e 70 50 67 20 29 20 62 48 69 74 20  s+1].pPg ) bHit 
14630 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = 1;.      }.   
14640 20 20 20 69 66 28 20 62 48 69 74 3d 3d 30 20 26     if( bHit==0 &
14650 26 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a  & rc==LSM_OK ){.
14660 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65 67          rc = seg
14670 6d 65 6e 74 50 74 72 45 6e 64 28 70 43 73 72 2c  mentPtrEnd(pCsr,
14680 20 70 50 74 72 2c 20 31 29 3b 0a 20 20 20 20 20   pPtr, 1);.     
14690 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
146a0 73 65 67 6d 65 6e 74 50 74 72 52 65 73 65 74 28  segmentPtrReset(
146b0 70 50 74 72 2c 20 4c 53 4d 5f 53 45 47 4d 45 4e  pPtr, LSM_SEGMEN
146c0 54 50 54 52 5f 46 52 45 45 5f 54 48 52 45 53 48  TPTR_FREE_THRESH
146d0 4f 4c 44 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  OLD);.      }.  
146e0 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69    }else{.      i
146f0 6e 74 20 62 4c 68 73 20 3d 20 28 70 50 74 72 2d  nt bLhs = (pPtr-
14700 3e 70 53 65 67 3d 3d 26 70 4c 76 6c 2d 3e 6c 68  >pSeg==&pLvl->lh
14710 73 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  s);.      assert
14720 28 20 70 50 74 72 2d 3e 70 53 65 67 3d 3d 26 70  ( pPtr->pSeg==&p
14730 4c 76 6c 2d 3e 6c 68 73 20 7c 7c 20 70 50 74 72  Lvl->lhs || pPtr
14740 2d 3e 70 53 65 67 3d 3d 26 70 4c 76 6c 2d 3e 61  ->pSeg==&pLvl->a
14750 52 68 73 5b 30 5d 20 29 3b 0a 0a 20 20 20 20 20  Rhs[0] );..     
14760 20 69 66 28 20 62 4c 68 73 20 29 7b 0a 20 20 20   if( bLhs ){.   
14770 20 20 20 20 20 72 63 20 3d 20 73 65 67 6d 65 6e       rc = segmen
14780 74 50 74 72 45 6e 64 28 70 43 73 72 2c 20 70 50  tPtrEnd(pCsr, pP
14790 74 72 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20  tr, 0);.        
147a0 69 66 28 20 70 50 74 72 2d 3e 70 4b 65 79 20 29  if( pPtr->pKey )
147b0 20 62 48 69 74 20 3d 20 31 3b 0a 20 20 20 20 20   bHit = 1;.     
147c0 20 7d 0a 20 20 20 20 20 20 66 6f 72 28 69 52 68   }.      for(iRh
147d0 73 3d 30 3b 20 69 52 68 73 3c 70 4c 76 6c 2d 3e  s=0; iRhs<pLvl->
147e0 6e 52 69 67 68 74 20 26 26 20 72 63 3d 3d 4c 53  nRight && rc==LS
147f0 4d 5f 4f 4b 3b 20 69 52 68 73 2b 2b 29 7b 0a 20  M_OK; iRhs++){. 
14800 20 20 20 20 20 20 20 69 66 28 20 62 48 69 74 20         if( bHit 
14810 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65 67  ){.          seg
14820 6d 65 6e 74 50 74 72 52 65 73 65 74 28 26 70 50  mentPtrReset(&pP
14830 74 72 5b 69 52 68 73 2b 31 5d 2c 20 4c 53 4d 5f  tr[iRhs+1], LSM_
14840 53 45 47 4d 45 4e 54 50 54 52 5f 46 52 45 45 5f  SEGMENTPTR_FREE_
14850 54 48 52 45 53 48 4f 4c 44 29 3b 0a 20 20 20 20  THRESHOLD);.    
14860 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
14870 20 20 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64       rc = sorted
14880 52 68 73 46 69 72 73 74 28 70 43 73 72 2c 20 70  RhsFirst(pCsr, p
14890 4c 76 6c 2c 20 26 70 50 74 72 5b 69 52 68 73 2b  Lvl, &pPtr[iRhs+
148a0 62 4c 68 73 5d 29 3b 0a 20 20 20 20 20 20 20 20  bLhs]);.        
148b0 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  }.      }.    }.
148c0 20 20 20 20 69 20 2b 3d 20 70 4c 76 6c 2d 3e 6e      i += pLvl->n
148d0 52 69 67 68 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  Right;.  }..  /*
148e0 20 41 6e 64 20 74 68 65 20 62 2d 74 72 65 65 20   And the b-tree 
148f0 63 75 72 73 6f 72 2c 20 69 66 20 61 70 70 6c 69  cursor, if appli
14900 63 61 62 6c 65 20 2a 2f 0a 20 20 69 66 28 20 72  cable */.  if( r
14910 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 43 73  c==LSM_OK && pCs
14920 72 2d 3e 70 42 74 43 73 72 20 29 7b 0a 20 20 20  r->pBtCsr ){.   
14930 20 61 73 73 65 72 74 28 20 62 4c 61 73 74 3d 3d   assert( bLast==
14940 30 20 29 3b 0a 20 20 20 20 72 63 20 3d 20 62 74  0 );.    rc = bt
14950 72 65 65 43 75 72 73 6f 72 46 69 72 73 74 28 70  reeCursorFirst(p
14960 43 73 72 2d 3e 70 42 74 43 73 72 29 3b 0a 20 20  Csr->pBtCsr);.  
14970 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d  }..  if( rc==LSM
14980 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
14990 6d 75 6c 74 69 43 75 72 73 6f 72 53 65 74 75 70  multiCursorSetup
149a0 54 72 65 65 28 70 43 73 72 2c 20 62 4c 61 73 74  Tree(pCsr, bLast
149b0 29 3b 0a 20 20 7d 0a 20 20 0a 20 20 72 65 74 75  );.  }.  .  retu
149c0 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 69 6e 74 20 6d  rn rc;.}...int m
149d0 63 75 72 73 6f 72 53 61 76 65 28 4d 75 6c 74 69  cursorSave(Multi
149e0 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20  Cursor *pCsr){. 
149f0 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
14a00 3b 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 61 54  ;.  if( pCsr->aT
14a10 72 65 65 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  ree ){.    int i
14a20 54 72 65 65 20 3d 20 70 43 73 72 2d 3e 61 54 72  Tree = pCsr->aTr
14a30 65 65 5b 31 5d 3b 0a 20 20 20 20 69 66 28 20 69  ee[1];.    if( i
14a40 54 72 65 65 3d 3d 43 55 52 53 4f 52 5f 44 41 54  Tree==CURSOR_DAT
14a50 41 5f 54 52 45 45 30 20 7c 7c 20 69 54 72 65 65  A_TREE0 || iTree
14a60 3d 3d 43 55 52 53 4f 52 5f 44 41 54 41 5f 54 52  ==CURSOR_DATA_TR
14a70 45 45 31 20 29 7b 0a 20 20 20 20 20 20 6d 75 6c  EE1 ){.      mul
14a80 74 69 43 75 72 73 6f 72 43 61 63 68 65 4b 65 79  tiCursorCacheKey
14a90 28 70 43 73 72 2c 20 26 72 63 29 3b 0a 20 20 20  (pCsr, &rc);.   
14aa0 20 7d 0a 20 20 7d 0a 20 20 6d 63 75 72 73 6f 72   }.  }.  mcursor
14ab0 46 72 65 65 43 6f 6d 70 6f 6e 65 6e 74 73 28 70  FreeComponents(p
14ac0 43 73 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  Csr);.  return r
14ad0 63 3b 0a 7d 0a 0a 69 6e 74 20 6d 63 75 72 73 6f  c;.}..int mcurso
14ae0 72 52 65 73 74 6f 72 65 28 6c 73 6d 5f 64 62 20  rRestore(lsm_db 
14af0 2a 70 44 62 2c 20 4d 75 6c 74 69 43 75 72 73 6f  *pDb, MultiCurso
14b00 72 20 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74 20  r *pCsr){.  int 
14b10 72 63 3b 0a 20 20 72 63 20 3d 20 6d 75 6c 74 69  rc;.  rc = multi
14b20 43 75 72 73 6f 72 49 6e 69 74 28 70 43 73 72 2c  CursorInit(pCsr,
14b30 20 70 44 62 2d 3e 70 43 6c 69 65 6e 74 29 3b 0a   pDb->pClient);.
14b40 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
14b50 20 26 26 20 70 43 73 72 2d 3e 6b 65 79 2e 70 44   && pCsr->key.pD
14b60 61 74 61 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  ata ){.    rc = 
14b70 6c 73 6d 4d 43 75 72 73 6f 72 53 65 65 6b 28 70  lsmMCursorSeek(p
14b80 43 73 72 2c 20 0a 20 20 20 20 20 20 20 20 20 72  Csr, .         r
14b90 74 54 6f 70 69 63 28 70 43 73 72 2d 3e 65 54 79  tTopic(pCsr->eTy
14ba0 70 65 29 2c 20 70 43 73 72 2d 3e 6b 65 79 2e 70  pe), pCsr->key.p
14bb0 44 61 74 61 2c 20 70 43 73 72 2d 3e 6b 65 79 2e  Data, pCsr->key.
14bc0 6e 44 61 74 61 2c 20 2b 31 0a 20 20 20 20 29 3b  nData, +1.    );
14bd0 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
14be0 3b 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 53 61 76 65  ;.}..int lsmSave
14bf0 43 75 72 73 6f 72 73 28 6c 73 6d 5f 64 62 20 2a  Cursors(lsm_db *
14c00 70 44 62 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  pDb){.  int rc =
14c10 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 4d 75 6c 74 69   LSM_OK;.  Multi
14c20 43 75 72 73 6f 72 20 2a 70 43 73 72 3b 0a 0a 20  Cursor *pCsr;.. 
14c30 20 66 6f 72 28 70 43 73 72 3d 70 44 62 2d 3e 70   for(pCsr=pDb->p
14c40 43 73 72 3b 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20  Csr; rc==LSM_OK 
14c50 26 26 20 70 43 73 72 3b 20 70 43 73 72 3d 70 43  && pCsr; pCsr=pC
14c60 73 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  sr->pNext){.    
14c70 72 63 20 3d 20 6d 63 75 72 73 6f 72 53 61 76 65  rc = mcursorSave
14c80 28 70 43 73 72 29 3b 0a 20 20 7d 0a 20 20 72 65  (pCsr);.  }.  re
14c90 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20  turn rc;.}..int 
14ca0 6c 73 6d 52 65 73 74 6f 72 65 43 75 72 73 6f 72  lsmRestoreCursor
14cb0 73 28 6c 73 6d 5f 64 62 20 2a 70 44 62 29 7b 0a  s(lsm_db *pDb){.
14cc0 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f    int rc = LSM_O
14cd0 4b 3b 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72  K;.  MultiCursor
14ce0 20 2a 70 43 73 72 3b 0a 0a 20 20 66 6f 72 28 70   *pCsr;..  for(p
14cf0 43 73 72 3d 70 44 62 2d 3e 70 43 73 72 3b 20 72  Csr=pDb->pCsr; r
14d00 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 43 73  c==LSM_OK && pCs
14d10 72 3b 20 70 43 73 72 3d 70 43 73 72 2d 3e 70 4e  r; pCsr=pCsr->pN
14d20 65 78 74 29 7b 0a 20 20 20 20 72 63 20 3d 20 6d  ext){.    rc = m
14d30 63 75 72 73 6f 72 52 65 73 74 6f 72 65 28 70 44  cursorRestore(pD
14d40 62 2c 20 70 43 73 72 29 3b 0a 20 20 7d 0a 20 20  b, pCsr);.  }.  
14d50 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e  return rc;.}..in
14d60 74 20 6c 73 6d 4d 43 75 72 73 6f 72 46 69 72 73  t lsmMCursorFirs
14d70 74 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70  t(MultiCursor *p
14d80 43 73 72 29 7b 0a 20 20 72 65 74 75 72 6e 20 6d  Csr){.  return m
14d90 75 6c 74 69 43 75 72 73 6f 72 45 6e 64 28 70 43  ultiCursorEnd(pC
14da0 73 72 2c 20 30 29 3b 0a 7d 0a 0a 69 6e 74 20 6c  sr, 0);.}..int l
14db0 73 6d 4d 43 75 72 73 6f 72 4c 61 73 74 28 4d 75  smMCursorLast(Mu
14dc0 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 29  ltiCursor *pCsr)
14dd0 7b 0a 20 20 72 65 74 75 72 6e 20 6d 75 6c 74 69  {.  return multi
14de0 43 75 72 73 6f 72 45 6e 64 28 70 43 73 72 2c 20  CursorEnd(pCsr, 
14df0 31 29 3b 0a 7d 0a 0a 6c 73 6d 5f 64 62 20 2a 6c  1);.}..lsm_db *l
14e00 73 6d 4d 43 75 72 73 6f 72 44 62 28 4d 75 6c 74  smMCursorDb(Mult
14e10 69 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a  iCursor *pCsr){.
14e20 20 20 72 65 74 75 72 6e 20 70 43 73 72 2d 3e 70    return pCsr->p
14e30 44 62 3b 0a 7d 0a 0a 76 6f 69 64 20 6c 73 6d 4d  Db;.}..void lsmM
14e40 43 75 72 73 6f 72 52 65 73 65 74 28 4d 75 6c 74  CursorReset(Mult
14e50 69 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a  iCursor *pCsr){.
14e60 20 20 69 6e 74 20 69 3b 0a 20 20 6c 73 6d 54 72    int i;.  lsmTr
14e70 65 65 43 75 72 73 6f 72 52 65 73 65 74 28 70 43  eeCursorReset(pC
14e80 73 72 2d 3e 61 70 54 72 65 65 43 73 72 5b 30 5d  sr->apTreeCsr[0]
14e90 29 3b 0a 20 20 6c 73 6d 54 72 65 65 43 75 72 73  );.  lsmTreeCurs
14ea0 6f 72 52 65 73 65 74 28 70 43 73 72 2d 3e 61 70  orReset(pCsr->ap
14eb0 54 72 65 65 43 73 72 5b 31 5d 29 3b 0a 20 20 66  TreeCsr[1]);.  f
14ec0 6f 72 28 69 3d 30 3b 20 69 3c 70 43 73 72 2d 3e  or(i=0; i<pCsr->
14ed0 6e 50 74 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nPtr; i++){.    
14ee0 73 65 67 6d 65 6e 74 50 74 72 52 65 73 65 74 28  segmentPtrReset(
14ef0 26 70 43 73 72 2d 3e 61 50 74 72 5b 69 5d 2c 20  &pCsr->aPtr[i], 
14f00 4c 53 4d 5f 53 45 47 4d 45 4e 54 50 54 52 5f 46  LSM_SEGMENTPTR_F
14f10 52 45 45 5f 54 48 52 45 53 48 4f 4c 44 29 3b 0a  REE_THRESHOLD);.
14f20 20 20 7d 0a 20 20 70 43 73 72 2d 3e 6b 65 79 2e    }.  pCsr->key.
14f30 6e 44 61 74 61 20 3d 20 30 3b 0a 7d 0a 0a 73 74  nData = 0;.}..st
14f40 61 74 69 63 20 69 6e 74 20 74 72 65 65 43 75 72  atic int treeCur
14f50 73 6f 72 53 65 65 6b 28 0a 20 20 4d 75 6c 74 69  sorSeek(.  Multi
14f60 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 0a 20 20  Cursor *pCsr,.  
14f70 54 72 65 65 43 75 72 73 6f 72 20 2a 70 54 72 65  TreeCursor *pTre
14f80 65 43 73 72 2c 20 0a 20 20 76 6f 69 64 20 2a 70  eCsr, .  void *p
14f90 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79 2c 20 0a  Key, int nKey, .
14fa0 20 20 69 6e 74 20 65 53 65 65 6b 2c 0a 20 20 69    int eSeek,.  i
14fb0 6e 74 20 2a 70 62 53 74 6f 70 0a 29 7b 0a 20 20  nt *pbStop.){.  
14fc0 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b  int rc = LSM_OK;
14fd0 0a 20 20 69 66 28 20 70 54 72 65 65 43 73 72 20  .  if( pTreeCsr 
14fe0 29 7b 0a 20 20 20 20 69 6e 74 20 72 65 73 20 3d  ){.    int res =
14ff0 20 30 3b 0a 20 20 20 20 6c 73 6d 54 72 65 65 43   0;.    lsmTreeC
15000 75 72 73 6f 72 53 65 65 6b 28 70 54 72 65 65 43  ursorSeek(pTreeC
15010 73 72 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 2c 20  sr, pKey, nKey, 
15020 26 72 65 73 29 3b 0a 20 20 20 20 73 77 69 74 63  &res);.    switc
15030 68 28 20 65 53 65 65 6b 20 29 7b 0a 20 20 20 20  h( eSeek ){.    
15040 20 20 63 61 73 65 20 4c 53 4d 5f 53 45 45 4b 5f    case LSM_SEEK_
15050 45 51 3a 20 7b 0a 20 20 20 20 20 20 20 20 69 6e  EQ: {.        in
15060 74 20 65 54 79 70 65 20 3d 20 6c 73 6d 54 72 65  t eType = lsmTre
15070 65 43 75 72 73 6f 72 46 6c 61 67 73 28 70 54 72  eCursorFlags(pTr
15080 65 65 43 73 72 29 3b 0a 20 20 20 20 20 20 20 20  eeCsr);.        
15090 69 66 28 20 28 72 65 73 3c 30 20 26 26 20 28 65  if( (res<0 && (e
150a0 54 79 70 65 20 26 20 4c 53 4d 5f 53 54 41 52 54  Type & LSM_START
150b0 5f 44 45 4c 45 54 45 29 29 0a 20 20 20 20 20 20  _DELETE)).      
150c0 20 20 20 7c 7c 20 28 72 65 73 3e 30 20 26 26 20     || (res>0 && 
150d0 28 65 54 79 70 65 20 26 20 4c 53 4d 5f 45 4e 44  (eType & LSM_END
150e0 5f 44 45 4c 45 54 45 29 29 0a 20 20 20 20 20 20  _DELETE)).      
150f0 20 20 20 7c 7c 20 28 72 65 73 3d 3d 30 20 26 26     || (res==0 &&
15100 20 28 65 54 79 70 65 20 26 20 4c 53 4d 5f 50 4f   (eType & LSM_PO
15110 49 4e 54 5f 44 45 4c 45 54 45 29 29 0a 20 20 20  INT_DELETE)).   
15120 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20       ){.        
15130 20 20 2a 70 62 53 74 6f 70 20 3d 20 31 3b 0a 20    *pbStop = 1;. 
15140 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28         }else if(
15150 20 72 65 73 3d 3d 30 20 26 26 20 28 65 54 79 70   res==0 && (eTyp
15160 65 20 26 20 4c 53 4d 5f 49 4e 53 45 52 54 29 20  e & LSM_INSERT) 
15170 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6c 73 6d  ){.          lsm
15180 5f 65 6e 76 20 2a 70 45 6e 76 20 3d 20 70 43 73  _env *pEnv = pCs
15190 72 2d 3e 70 44 62 2d 3e 70 45 6e 76 3b 0a 20 20  r->pDb->pEnv;.  
151a0 20 20 20 20 20 20 20 20 76 6f 69 64 20 2a 70 3b          void *p;
151b0 20 69 6e 74 20 6e 3b 20 20 20 20 20 20 20 20 20   int n;         
151c0 2f 2a 20 4b 65 79 2f 76 61 6c 75 65 20 66 72 6f  /* Key/value fro
151d0 6d 20 74 72 65 65 2d 63 75 72 73 6f 72 20 2a 2f  m tree-cursor */
151e0 0a 20 20 20 20 20 20 20 20 20 20 2a 70 62 53 74  .          *pbSt
151f0 6f 70 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  op = 1;.        
15200 20 20 70 43 73 72 2d 3e 66 6c 61 67 73 20 7c 3d    pCsr->flags |=
15210 20 43 55 52 53 4f 52 5f 53 45 45 4b 5f 45 51 3b   CURSOR_SEEK_EQ;
15220 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
15230 6c 73 6d 54 72 65 65 43 75 72 73 6f 72 4b 65 79  lsmTreeCursorKey
15240 28 70 54 72 65 65 43 73 72 2c 20 26 70 43 73 72  (pTreeCsr, &pCsr
15250 2d 3e 65 54 79 70 65 2c 20 26 70 2c 20 26 6e 29  ->eType, &p, &n)
15260 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
15270 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 20 72 63 20  rc==LSM_OK ) rc 
15280 3d 20 73 6f 72 74 65 64 42 6c 6f 62 53 65 74 28  = sortedBlobSet(
15290 70 45 6e 76 2c 20 26 70 43 73 72 2d 3e 6b 65 79  pEnv, &pCsr->key
152a0 2c 20 70 2c 20 6e 29 3b 0a 20 20 20 20 20 20 20  , p, n);.       
152b0 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
152c0 4b 20 29 20 72 63 20 3d 20 6c 73 6d 54 72 65 65  K ) rc = lsmTree
152d0 43 75 72 73 6f 72 56 61 6c 75 65 28 70 54 72 65  CursorValue(pTre
152e0 65 43 73 72 2c 20 26 70 2c 20 26 6e 29 3b 0a 20  eCsr, &p, &n);. 
152f0 20 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d           if( rc=
15300 3d 4c 53 4d 5f 4f 4b 20 29 20 72 63 20 3d 20 73  =LSM_OK ) rc = s
15310 6f 72 74 65 64 42 6c 6f 62 53 65 74 28 70 45 6e  ortedBlobSet(pEn
15320 76 2c 20 26 70 43 73 72 2d 3e 76 61 6c 2c 20 70  v, &pCsr->val, p
15330 2c 20 6e 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  , n);.        }.
15340 20 20 20 20 20 20 20 20 6c 73 6d 54 72 65 65 43          lsmTreeC
15350 75 72 73 6f 72 52 65 73 65 74 28 70 54 72 65 65  ursorReset(pTree
15360 43 73 72 29 3b 0a 20 20 20 20 20 20 20 20 62 72  Csr);.        br
15370 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
15380 20 20 20 63 61 73 65 20 4c 53 4d 5f 53 45 45 4b     case LSM_SEEK
15390 5f 47 45 3a 0a 20 20 20 20 20 20 20 20 69 66 28  _GE:.        if(
153a0 20 72 65 73 3c 30 20 26 26 20 6c 73 6d 54 72 65   res<0 && lsmTre
153b0 65 43 75 72 73 6f 72 56 61 6c 69 64 28 70 54 72  eCursorValid(pTr
153c0 65 65 43 73 72 29 20 29 7b 0a 20 20 20 20 20 20  eeCsr) ){.      
153d0 20 20 20 20 6c 73 6d 54 72 65 65 43 75 72 73 6f      lsmTreeCurso
153e0 72 4e 65 78 74 28 70 54 72 65 65 43 73 72 29 3b  rNext(pTreeCsr);
153f0 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
15400 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
15410 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 20  default:.       
15420 20 69 66 28 20 72 65 73 3e 30 20 29 7b 0a 20 20   if( res>0 ){.  
15430 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
15440 6c 73 6d 54 72 65 65 43 75 72 73 6f 72 56 61 6c  lsmTreeCursorVal
15450 69 64 28 70 54 72 65 65 43 73 72 29 20 29 3b 0a  id(pTreeCsr) );.
15460 20 20 20 20 20 20 20 20 20 20 6c 73 6d 54 72 65            lsmTre
15470 65 43 75 72 73 6f 72 50 72 65 76 28 70 54 72 65  eCursorPrev(pTre
15480 65 43 73 72 29 3b 0a 20 20 20 20 20 20 20 20 7d  eCsr);.        }
15490 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
154a0 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
154b0 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  rn rc;.}.../*.**
154c0 20 53 65 65 6b 20 74 68 65 20 63 75 72 73 6f 72   Seek the cursor
154d0 2e 0a 2a 2f 0a 69 6e 74 20 6c 73 6d 4d 43 75 72  ..*/.int lsmMCur
154e0 73 6f 72 53 65 65 6b 28 0a 20 20 4d 75 6c 74 69  sorSeek(.  Multi
154f0 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 0a 20  Cursor *pCsr, . 
15500 20 69 6e 74 20 69 54 6f 70 69 63 2c 20 0a 20 20   int iTopic, .  
15510 76 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20  void *pKey, int 
15520 6e 4b 65 79 2c 20 0a 20 20 69 6e 74 20 65 53 65  nKey, .  int eSe
15530 65 6b 0a 29 7b 0a 20 20 69 6e 74 20 65 45 53 65  ek.){.  int eESe
15540 65 6b 20 3d 20 65 53 65 65 6b 3b 20 20 20 20 20  ek = eSeek;     
15550 20 20 20 20 20 20 20 20 2f 2a 20 45 66 66 65 63          /* Effec
15560 74 69 76 65 20 65 53 65 65 6b 20 70 61 72 61 6d  tive eSeek param
15570 65 74 65 72 20 2a 2f 0a 20 20 69 6e 74 20 62 53  eter */.  int bS
15580 74 6f 70 20 3d 20 30 3b 20 20 20 20 20 20 20 20  top = 0;        
15590 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74            /* Set
155a0 20 74 6f 20 74 72 75 65 20 74 6f 20 68 61 6c 74   to true to halt
155b0 20 73 65 61 72 63 68 20 6f 70 65 72 61 74 69 6f   search operatio
155c0 6e 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20  n */.  int rc = 
155d0 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  LSM_OK;         
155e0 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
155f0 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69   code */.  int i
15600 50 74 72 20 3d 20 30 3b 20 20 20 20 20 20 20 20  Ptr = 0;        
15610 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73             /* Us
15620 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74 68  ed to iterate th
15630 72 6f 75 67 68 20 70 43 73 72 2d 3e 61 50 74 72  rough pCsr->aPtr
15640 5b 5d 20 2a 2f 0a 20 20 50 67 6e 6f 20 69 50 67  [] */.  Pgno iPg
15650 6e 6f 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  no = 0;         
15660 20 20 20 20 20 20 20 20 2f 2a 20 46 43 20 70 6f          /* FC po
15670 69 6e 74 65 72 20 76 61 6c 75 65 20 2a 2f 0a 0a  inter value */..
15680 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
15690 61 70 54 72 65 65 43 73 72 5b 30 5d 3d 3d 30 20  apTreeCsr[0]==0 
156a0 7c 7c 20 69 54 6f 70 69 63 3d 3d 30 20 29 3b 0a  || iTopic==0 );.
156b0 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
156c0 61 70 54 72 65 65 43 73 72 5b 31 5d 3d 3d 30 20  apTreeCsr[1]==0 
156d0 7c 7c 20 69 54 6f 70 69 63 3d 3d 30 20 29 3b 0a  || iTopic==0 );.
156e0 0a 20 20 69 66 28 20 65 45 53 65 65 6b 3d 3d 4c  .  if( eESeek==L
156f0 53 4d 5f 53 45 45 4b 5f 4c 45 46 41 53 54 20 29  SM_SEEK_LEFAST )
15700 20 65 45 53 65 65 6b 20 3d 20 4c 53 4d 5f 53 45   eESeek = LSM_SE
15710 45 4b 5f 4c 45 3b 0a 0a 20 20 61 73 73 65 72 74  EK_LE;..  assert
15720 28 20 65 45 53 65 65 6b 3d 3d 4c 53 4d 5f 53 45  ( eESeek==LSM_SE
15730 45 4b 5f 45 51 20 7c 7c 20 65 45 53 65 65 6b 3d  EK_EQ || eESeek=
15740 3d 4c 53 4d 5f 53 45 45 4b 5f 4c 45 20 7c 7c 20  =LSM_SEEK_LE || 
15750 65 45 53 65 65 6b 3d 3d 4c 53 4d 5f 53 45 45 4b  eESeek==LSM_SEEK
15760 5f 47 45 20 29 3b 0a 20 20 61 73 73 65 72 74 28  _GE );.  assert(
15770 20 28 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20   (pCsr->flags & 
15780 43 55 52 53 4f 52 5f 46 4c 55 53 48 5f 46 52 45  CURSOR_FLUSH_FRE
15790 45 4c 49 53 54 29 3d 3d 30 20 29 3b 0a 20 20 61  ELIST)==0 );.  a
157a0 73 73 65 72 74 28 20 70 43 73 72 2d 3e 6e 50 74  ssert( pCsr->nPt
157b0 72 3d 3d 30 20 7c 7c 20 70 43 73 72 2d 3e 61 50  r==0 || pCsr->aP
157c0 74 72 5b 30 5d 2e 70 4c 65 76 65 6c 20 29 3b 0a  tr[0].pLevel );.
157d0 0a 20 20 70 43 73 72 2d 3e 66 6c 61 67 73 20 26  .  pCsr->flags &
157e0 3d 20 7e 28 43 55 52 53 4f 52 5f 4e 45 58 54 5f  = ~(CURSOR_NEXT_
157f0 4f 4b 20 7c 20 43 55 52 53 4f 52 5f 50 52 45 56  OK | CURSOR_PREV
15800 5f 4f 4b 20 7c 20 43 55 52 53 4f 52 5f 53 45 45  _OK | CURSOR_SEE
15810 4b 5f 45 51 29 3b 0a 20 20 72 63 20 3d 20 74 72  K_EQ);.  rc = tr
15820 65 65 43 75 72 73 6f 72 53 65 65 6b 28 70 43 73  eeCursorSeek(pCs
15830 72 2c 20 70 43 73 72 2d 3e 61 70 54 72 65 65 43  r, pCsr->apTreeC
15840 73 72 5b 30 5d 2c 20 70 4b 65 79 2c 20 6e 4b 65  sr[0], pKey, nKe
15850 79 2c 20 65 45 53 65 65 6b 2c 20 26 62 53 74 6f  y, eESeek, &bSto
15860 70 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53  p);.  if( rc==LS
15870 4d 5f 4f 4b 20 26 26 20 62 53 74 6f 70 3d 3d 30  M_OK && bStop==0
15880 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 74 72 65   ){.    rc = tre
15890 65 43 75 72 73 6f 72 53 65 65 6b 28 70 43 73 72  eCursorSeek(pCsr
158a0 2c 20 70 43 73 72 2d 3e 61 70 54 72 65 65 43 73  , pCsr->apTreeCs
158b0 72 5b 31 5d 2c 20 70 4b 65 79 2c 20 6e 4b 65 79  r[1], pKey, nKey
158c0 2c 20 65 45 53 65 65 6b 2c 20 26 62 53 74 6f 70  , eESeek, &bStop
158d0 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 65 65  );.  }..  /* See
158e0 6b 20 61 6c 6c 20 73 65 67 6d 65 6e 74 20 70 6f  k all segment po
158f0 69 6e 74 65 72 73 2e 20 2a 2f 0a 20 20 66 6f 72  inters. */.  for
15900 28 69 50 74 72 3d 30 3b 20 69 50 74 72 3c 70 43  (iPtr=0; iPtr<pC
15910 73 72 2d 3e 6e 50 74 72 20 26 26 20 72 63 3d 3d  sr->nPtr && rc==
15920 4c 53 4d 5f 4f 4b 20 26 26 20 62 53 74 6f 70 3d  LSM_OK && bStop=
15930 3d 30 3b 20 69 50 74 72 2b 2b 29 7b 0a 20 20 20  =0; iPtr++){.   
15940 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74   SegmentPtr *pPt
15950 72 20 3d 20 26 70 43 73 72 2d 3e 61 50 74 72 5b  r = &pCsr->aPtr[
15960 69 50 74 72 5d 3b 0a 20 20 20 20 61 73 73 65 72  iPtr];.    asser
15970 74 28 20 70 50 74 72 2d 3e 70 53 65 67 3d 3d 26  t( pPtr->pSeg==&
15980 70 50 74 72 2d 3e 70 4c 65 76 65 6c 2d 3e 6c 68  pPtr->pLevel->lh
15990 73 20 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 65  s );.    rc = se
159a0 65 6b 49 6e 4c 65 76 65 6c 28 70 43 73 72 2c 20  ekInLevel(pCsr, 
159b0 70 50 74 72 2c 20 65 45 53 65 65 6b 2c 20 69 54  pPtr, eESeek, iT
159c0 6f 70 69 63 2c 20 70 4b 65 79 2c 20 6e 4b 65 79  opic, pKey, nKey
159d0 2c 20 26 69 50 67 6e 6f 2c 20 26 62 53 74 6f 70  , &iPgno, &bStop
159e0 29 3b 0a 20 20 20 20 69 50 74 72 20 2b 3d 20 70  );.    iPtr += p
159f0 50 74 72 2d 3e 70 4c 65 76 65 6c 2d 3e 6e 52 69  Ptr->pLevel->nRi
15a00 67 68 74 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  ght;.  }..  if( 
15a10 65 53 65 65 6b 21 3d 4c 53 4d 5f 53 45 45 4b 5f  eSeek!=LSM_SEEK_
15a20 45 51 20 29 7b 0a 20 20 20 20 69 66 28 20 72 63  EQ ){.    if( rc
15a30 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20  ==LSM_OK ){.    
15a40 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75 72 73    rc = multiCurs
15a50 6f 72 41 6c 6c 6f 63 54 72 65 65 28 70 43 73 72  orAllocTree(pCsr
15a60 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
15a70 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20   rc==LSM_OK ){. 
15a80 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20       int i;.    
15a90 20 20 66 6f 72 28 69 3d 70 43 73 72 2d 3e 6e 54    for(i=pCsr->nT
15aa0 72 65 65 2d 31 3b 20 69 3e 30 3b 20 69 2d 2d 29  ree-1; i>0; i--)
15ab0 7b 0a 20 20 20 20 20 20 20 20 6d 75 6c 74 69 43  {.        multiC
15ac0 75 72 73 6f 72 44 6f 43 6f 6d 70 61 72 65 28 70  ursorDoCompare(p
15ad0 43 73 72 2c 20 69 2c 20 65 45 53 65 65 6b 3d 3d  Csr, i, eESeek==
15ae0 4c 53 4d 5f 53 45 45 4b 5f 4c 45 29 3b 0a 20 20  LSM_SEEK_LE);.  
15af0 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
15b00 65 53 65 65 6b 3d 3d 4c 53 4d 5f 53 45 45 4b 5f  eSeek==LSM_SEEK_
15b10 47 45 20 29 20 70 43 73 72 2d 3e 66 6c 61 67 73  GE ) pCsr->flags
15b20 20 7c 3d 20 43 55 52 53 4f 52 5f 4e 45 58 54 5f   |= CURSOR_NEXT_
15b30 4f 4b 3b 0a 20 20 20 20 20 20 69 66 28 20 65 53  OK;.      if( eS
15b40 65 65 6b 3d 3d 4c 53 4d 5f 53 45 45 4b 5f 4c 45  eek==LSM_SEEK_LE
15b50 20 29 20 70 43 73 72 2d 3e 66 6c 61 67 73 20 7c   ) pCsr->flags |
15b60 3d 20 43 55 52 53 4f 52 5f 50 52 45 56 5f 4f 4b  = CURSOR_PREV_OK
15b70 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 6d 75 6c  ;.    }..    mul
15b80 74 69 43 75 72 73 6f 72 43 61 63 68 65 4b 65 79  tiCursorCacheKey
15b90 28 70 43 73 72 2c 20 26 72 63 29 3b 0a 20 20 20  (pCsr, &rc);.   
15ba0 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
15bb0 26 26 20 65 53 65 65 6b 21 3d 4c 53 4d 5f 53 45  && eSeek!=LSM_SE
15bc0 45 4b 5f 4c 45 46 41 53 54 20 26 26 20 30 3d 3d  EK_LEFAST && 0==
15bd0 6d 63 75 72 73 6f 72 4c 6f 63 61 74 69 6f 6e 4f  mcursorLocationO
15be0 6b 28 70 43 73 72 2c 20 30 29 20 29 7b 0a 20 20  k(pCsr, 0) ){.  
15bf0 20 20 20 20 73 77 69 74 63 68 28 20 65 45 53 65      switch( eESe
15c00 65 6b 20 29 7b 0a 20 20 20 20 20 20 20 20 63 61  ek ){.        ca
15c10 73 65 20 4c 53 4d 5f 53 45 45 4b 5f 45 51 3a 0a  se LSM_SEEK_EQ:.
15c20 20 20 20 20 20 20 20 20 20 20 6c 73 6d 4d 43 75            lsmMCu
15c30 72 73 6f 72 52 65 73 65 74 28 70 43 73 72 29 3b  rsorReset(pCsr);
15c40 0a 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b  .          break
15c50 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 4c  ;.        case L
15c60 53 4d 5f 53 45 45 4b 5f 47 45 3a 0a 20 20 20 20  SM_SEEK_GE:.    
15c70 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 4d 43        rc = lsmMC
15c80 75 72 73 6f 72 4e 65 78 74 28 70 43 73 72 29 3b  ursorNext(pCsr);
15c90 0a 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b  .          break
15ca0 3b 0a 20 20 20 20 20 20 20 20 64 65 66 61 75 6c  ;.        defaul
15cb0 74 3a 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  t:.          rc 
15cc0 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 50 72 65 76  = lsmMCursorPrev
15cd0 28 70 43 73 72 29 3b 0a 20 20 20 20 20 20 20 20  (pCsr);.        
15ce0 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d    break;.      }
15cf0 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
15d00 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20  turn rc;.}..int 
15d10 6c 73 6d 4d 43 75 72 73 6f 72 56 61 6c 69 64 28  lsmMCursorValid(
15d20 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73  MultiCursor *pCs
15d30 72 29 7b 0a 20 20 69 6e 74 20 72 65 73 20 3d 20  r){.  int res = 
15d40 30 3b 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 66  0;.  if( pCsr->f
15d50 6c 61 67 73 20 26 20 43 55 52 53 4f 52 5f 53 45  lags & CURSOR_SE
15d60 45 4b 5f 45 51 20 29 7b 0a 20 20 20 20 72 65 73  EK_EQ ){.    res
15d70 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 65 20 69 66   = 1;.  }else if
15d80 28 20 70 43 73 72 2d 3e 61 54 72 65 65 20 29 7b  ( pCsr->aTree ){
15d90 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 20 3d 20  .    int iKey = 
15da0 70 43 73 72 2d 3e 61 54 72 65 65 5b 31 5d 3b 0a  pCsr->aTree[1];.
15db0 20 20 20 20 69 66 28 20 69 4b 65 79 3d 3d 43 55      if( iKey==CU
15dc0 52 53 4f 52 5f 44 41 54 41 5f 54 52 45 45 30 20  RSOR_DATA_TREE0 
15dd0 7c 7c 20 69 4b 65 79 3d 3d 43 55 52 53 4f 52 5f  || iKey==CURSOR_
15de0 44 41 54 41 5f 54 52 45 45 31 20 29 7b 0a 20 20  DATA_TREE1 ){.  
15df0 20 20 20 20 72 65 73 20 3d 20 6c 73 6d 54 72 65      res = lsmTre
15e00 65 43 75 72 73 6f 72 56 61 6c 69 64 28 70 43 73  eCursorValid(pCs
15e10 72 2d 3e 61 70 54 72 65 65 43 73 72 5b 69 4b 65  r->apTreeCsr[iKe
15e20 79 2d 43 55 52 53 4f 52 5f 44 41 54 41 5f 54 52  y-CURSOR_DATA_TR
15e30 45 45 30 5d 29 3b 0a 20 20 20 20 7d 65 6c 73 65  EE0]);.    }else
15e40 7b 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70 4b  {.      void *pK
15e50 65 79 3b 20 0a 20 20 20 20 20 20 6d 75 6c 74 69  ey; .      multi
15e60 43 75 72 73 6f 72 47 65 74 4b 65 79 28 70 43 73  CursorGetKey(pCs
15e70 72 2c 20 69 4b 65 79 2c 20 30 2c 20 26 70 4b 65  r, iKey, 0, &pKe
15e80 79 2c 20 30 29 3b 0a 20 20 20 20 20 20 72 65 73  y, 0);.      res
15e90 20 3d 20 70 4b 65 79 21 3d 30 3b 0a 20 20 20 20   = pKey!=0;.    
15ea0 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  }.  }.  return r
15eb0 65 73 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  es;.}..static in
15ec0 74 20 6d 63 75 72 73 6f 72 41 64 76 61 6e 63 65  t mcursorAdvance
15ed0 4f 6b 28 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f  Ok(.  MultiCurso
15ee0 72 20 2a 70 43 73 72 2c 20 0a 20 20 69 6e 74 20  r *pCsr, .  int 
15ef0 62 52 65 76 65 72 73 65 2c 0a 20 20 69 6e 74 20  bReverse,.  int 
15f00 2a 70 52 63 0a 29 7b 0a 20 20 76 6f 69 64 20 2a  *pRc.){.  void *
15f10 70 4e 65 77 3b 20 20 20 20 20 20 20 20 20 20 20  pNew;           
15f20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
15f30 6e 74 65 72 20 74 6f 20 62 75 66 66 65 72 20 63  nter to buffer c
15f40 6f 6e 74 61 69 6e 69 6e 67 20 6e 65 77 20 6b 65  ontaining new ke
15f50 79 20 2a 2f 0a 20 20 69 6e 74 20 6e 4e 65 77 3b  y */.  int nNew;
15f60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15f70 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
15f80 66 20 62 75 66 66 65 72 20 70 4e 65 77 20 69 6e  f buffer pNew in
15f90 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20   bytes */.  int 
15fa0 65 4e 65 77 54 79 70 65 3b 20 20 20 20 20 20 20  eNewType;       
15fb0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
15fc0 79 70 65 20 6f 66 20 6e 65 77 20 72 65 63 6f 72  ype of new recor
15fd0 64 20 2a 2f 0a 0a 20 20 69 66 28 20 2a 70 52 63  d */..  if( *pRc
15fe0 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 0a 20 20   ) return 1;..  
15ff0 2f 2a 20 43 68 65 63 6b 20 74 68 65 20 63 75 72  /* Check the cur
16000 72 65 6e 74 20 6b 65 79 20 76 61 6c 75 65 2e 20  rent key value. 
16010 49 66 20 69 74 20 69 73 20 6e 6f 74 20 67 72 65  If it is not gre
16020 61 74 65 72 20 74 68 61 6e 20 28 69 66 20 62 52  ater than (if bR
16030 65 76 65 72 73 65 3d 3d 30 29 0a 20 20 2a 2a 20  everse==0).  ** 
16040 6f 72 20 6c 65 73 73 20 74 68 61 6e 20 28 69 66  or less than (if
16050 20 62 52 65 76 65 72 73 65 21 3d 30 29 20 74 68   bReverse!=0) th
16060 65 20 6b 65 79 20 63 75 72 72 65 6e 74 6c 79 20  e key currently 
16070 63 61 63 68 65 64 20 69 6e 20 70 43 73 72 2d 3e  cached in pCsr->
16080 6b 65 79 2c 20 0a 20 20 2a 2a 20 74 68 65 6e 20  key, .  ** then 
16090 74 68 65 20 63 75 72 73 6f 72 20 68 61 73 20 6e  the cursor has n
160a0 6f 74 20 79 65 74 20 62 65 65 6e 20 73 75 63 63  ot yet been succ
160b0 65 73 73 66 75 6c 6c 79 20 61 64 76 61 6e 63 65  essfully advance
160c0 64 2e 20 20 0a 20 20 2a 2f 0a 20 20 6d 75 6c 74  d.  .  */.  mult
160d0 69 43 75 72 73 6f 72 47 65 74 4b 65 79 28 70 43  iCursorGetKey(pC
160e0 73 72 2c 20 70 43 73 72 2d 3e 61 54 72 65 65 5b  sr, pCsr->aTree[
160f0 31 5d 2c 20 26 65 4e 65 77 54 79 70 65 2c 20 26  1], &eNewType, &
16100 70 4e 65 77 2c 20 26 6e 4e 65 77 29 3b 0a 20 20  pNew, &nNew);.  
16110 69 66 28 20 70 4e 65 77 20 29 7b 0a 20 20 20 20  if( pNew ){.    
16120 69 6e 74 20 74 79 70 65 6d 61 73 6b 20 3d 20 28  int typemask = (
16130 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20 43 55  pCsr->flags & CU
16140 52 53 4f 52 5f 49 47 4e 4f 52 45 5f 44 45 4c 45  RSOR_IGNORE_DELE
16150 54 45 29 20 3f 20 7e 28 30 29 20 3a 20 4c 53 4d  TE) ? ~(0) : LSM
16160 5f 53 59 53 54 45 4d 4b 45 59 3b 0a 20 20 20 20  _SYSTEMKEY;.    
16170 69 6e 74 20 72 65 73 20 3d 20 73 6f 72 74 65 64  int res = sorted
16180 44 62 4b 65 79 43 6f 6d 70 61 72 65 28 70 43 73  DbKeyCompare(pCs
16190 72 2c 0a 20 20 20 20 20 20 65 4e 65 77 54 79 70  r,.      eNewTyp
161a0 65 20 26 20 74 79 70 65 6d 61 73 6b 2c 20 70 4e  e & typemask, pN
161b0 65 77 2c 20 6e 4e 65 77 2c 20 0a 20 20 20 20 20  ew, nNew, .     
161c0 20 70 43 73 72 2d 3e 65 54 79 70 65 20 26 20 74   pCsr->eType & t
161d0 79 70 65 6d 61 73 6b 2c 20 70 43 73 72 2d 3e 6b  ypemask, pCsr->k
161e0 65 79 2e 70 44 61 74 61 2c 20 70 43 73 72 2d 3e  ey.pData, pCsr->
161f0 6b 65 79 2e 6e 44 61 74 61 0a 20 20 20 20 29 3b  key.nData.    );
16200 0a 0a 20 20 20 20 69 66 28 20 28 62 52 65 76 65  ..    if( (bReve
16210 72 73 65 3d 3d 30 20 26 26 20 72 65 73 3c 3d 30  rse==0 && res<=0
16220 29 20 7c 7c 20 28 62 52 65 76 65 72 73 65 21 3d  ) || (bReverse!=
16230 30 20 26 26 20 72 65 73 3e 3d 30 29 20 29 7b 0a  0 && res>=0) ){.
16240 20 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a        return 0;.
16250 20 20 20 20 7d 0a 0a 20 20 20 20 6d 75 6c 74 69      }..    multi
16260 43 75 72 73 6f 72 43 61 63 68 65 4b 65 79 28 70  CursorCacheKey(p
16270 43 73 72 2c 20 70 52 63 29 3b 0a 20 20 20 20 61  Csr, pRc);.    a
16280 73 73 65 72 74 28 20 70 43 73 72 2d 3e 65 54 79  ssert( pCsr->eTy
16290 70 65 3d 3d 65 4e 65 77 54 79 70 65 20 29 3b 0a  pe==eNewType );.
162a0 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 69 73 20  .    /* If this 
162b0 63 75 72 73 6f 72 20 69 73 20 63 6f 6e 66 69 67  cursor is config
162c0 75 72 65 64 20 74 6f 20 73 6b 69 70 20 64 65 6c  ured to skip del
162d0 65 74 65 64 20 6b 65 79 73 2c 20 61 6e 64 20 74  eted keys, and t
162e0 68 65 20 63 75 72 72 65 6e 74 0a 20 20 20 20 2a  he current.    *
162f0 2a 20 63 75 72 73 6f 72 20 70 6f 69 6e 74 73 20  * cursor points 
16300 74 6f 20 61 20 53 4f 52 54 45 44 5f 44 45 4c 45  to a SORTED_DELE
16310 54 45 20 65 6e 74 72 79 2c 20 74 68 65 6e 20 74  TE entry, then t
16320 68 65 20 63 75 72 73 6f 72 20 68 61 73 20 6e 6f  he cursor has no
16330 74 20 62 65 65 6e 20 0a 20 20 20 20 2a 2a 20 73  t been .    ** s
16340 75 63 63 65 73 73 66 75 6c 6c 79 20 61 64 76 61  uccessfully adva
16350 6e 63 65 64 2e 20 20 0a 20 20 20 20 2a 2a 0a 20  nced.  .    **. 
16360 20 20 20 2a 2a 20 53 69 6d 69 6c 61 72 6c 79 2c     ** Similarly,
16370 20 69 66 20 74 68 65 20 63 75 72 73 6f 72 20 69   if the cursor i
16380 73 20 63 6f 6e 66 69 67 75 72 65 64 20 74 6f 20  s configured to 
16390 73 6b 69 70 20 73 79 73 74 65 6d 20 6b 65 79 73  skip system keys
163a0 20 61 6e 64 20 74 68 65 0a 20 20 20 20 2a 2a 20   and the.    ** 
163b0 63 75 72 72 65 6e 74 20 63 75 72 73 6f 72 20 70  current cursor p
163c0 6f 69 6e 74 73 20 74 6f 20 61 20 73 79 73 74 65  oints to a syste
163d0 6d 20 6b 65 79 2c 20 69 74 20 68 61 73 20 6e 6f  m key, it has no
163e0 74 20 79 65 74 20 62 65 65 6e 20 61 64 76 61 6e  t yet been advan
163f0 63 65 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ced..    */.    
16400 69 66 28 20 2a 70 52 63 3d 3d 4c 53 4d 5f 4f 4b  if( *pRc==LSM_OK
16410 20 26 26 20 30 3d 3d 6d 63 75 72 73 6f 72 4c 6f   && 0==mcursorLo
16420 63 61 74 69 6f 6e 4f 6b 28 70 43 73 72 2c 20 30  cationOk(pCsr, 0
16430 29 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20  ) ) return 0;.  
16440 7d 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a  }.  return 1;.}.
16450 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 6c 43  .static void flC
16460 73 72 41 64 76 61 6e 63 65 28 4d 75 6c 74 69 43  srAdvance(MultiC
16470 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20  ursor *pCsr){.  
16480 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e 66 6c  assert( pCsr->fl
16490 61 67 73 20 26 20 43 55 52 53 4f 52 5f 46 4c 55  ags & CURSOR_FLU
164a0 53 48 5f 46 52 45 45 4c 49 53 54 20 29 3b 0a 20  SH_FREELIST );. 
164b0 20 69 66 28 20 70 43 73 72 2d 3e 69 46 72 65 65   if( pCsr->iFree
164c0 20 25 20 32 20 29 7b 0a 20 20 20 20 70 43 73 72   % 2 ){.    pCsr
164d0 2d 3e 69 46 72 65 65 2b 2b 3b 0a 20 20 7d 65 6c  ->iFree++;.  }el
164e0 73 65 7b 0a 20 20 20 20 69 6e 74 20 6e 45 6e 74  se{.    int nEnt
164f0 72 79 20 3d 20 70 43 73 72 2d 3e 70 44 62 2d 3e  ry = pCsr->pDb->
16500 70 57 6f 72 6b 65 72 2d 3e 66 72 65 65 6c 69 73  pWorker->freelis
16510 74 2e 6e 45 6e 74 72 79 3b 0a 20 20 20 20 46 72  t.nEntry;.    Fr
16520 65 65 6c 69 73 74 45 6e 74 72 79 20 2a 61 45 6e  eelistEntry *aEn
16530 74 72 79 20 3d 20 70 43 73 72 2d 3e 70 44 62 2d  try = pCsr->pDb-
16540 3e 70 57 6f 72 6b 65 72 2d 3e 66 72 65 65 6c 69  >pWorker->freeli
16550 73 74 2e 61 45 6e 74 72 79 3b 0a 0a 20 20 20 20  st.aEntry;..    
16560 69 6e 74 20 69 20 3d 20 6e 45 6e 74 72 79 20 2d  int i = nEntry -
16570 20 31 20 2d 20 28 70 43 73 72 2d 3e 69 46 72 65   1 - (pCsr->iFre
16580 65 20 2f 20 32 29 3b 0a 0a 20 20 20 20 2f 2a 20  e / 2);..    /* 
16590 49 66 20 74 68 65 20 63 75 72 72 65 6e 74 20 65  If the current e
165a0 6e 74 72 79 20 69 73 20 61 20 64 65 6c 65 74 65  ntry is a delete
165b0 20 61 6e 64 20 74 68 65 20 22 65 6e 64 2d 64 65   and the "end-de
165c0 6c 65 74 65 22 20 6b 65 79 20 77 69 6c 6c 20 6e  lete" key will n
165d0 6f 74 0a 20 20 20 20 2a 2a 20 62 65 20 61 74 74  ot.    ** be att
165e0 61 63 68 65 64 20 74 6f 20 74 68 65 20 6e 65 78  ached to the nex
165f0 74 20 65 6e 74 72 79 2c 20 69 6e 63 72 65 6d 65  t entry, increme
16600 6e 74 20 69 46 72 65 65 20 62 79 20 31 20 6f 6e  nt iFree by 1 on
16610 6c 79 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 61  ly. */.    if( a
16620 45 6e 74 72 79 5b 69 5d 2e 69 49 64 3c 30 20 29  Entry[i].iId<0 )
16630 7b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 31  {.      while( 1
16640 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
16650 69 3d 3d 30 20 7c 7c 20 61 45 6e 74 72 79 5b 69  i==0 || aEntry[i
16660 2d 31 5d 2e 69 42 6c 6b 21 3d 61 45 6e 74 72 79  -1].iBlk!=aEntry
16670 5b 69 5d 2e 69 42 6c 6b 2d 31 20 29 7b 0a 20 20  [i].iBlk-1 ){.  
16680 20 20 20 20 20 20 20 20 70 43 73 72 2d 3e 69 46          pCsr->iF
16690 72 65 65 2d 2d 3b 0a 20 20 20 20 20 20 20 20 20  ree--;.         
166a0 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
166b0 7d 0a 20 20 20 20 20 20 20 20 69 66 28 20 61 45  }.        if( aE
166c0 6e 74 72 79 5b 69 2d 31 5d 2e 69 49 64 3e 3d 30  ntry[i-1].iId>=0
166d0 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20   ) break;.      
166e0 20 20 70 43 73 72 2d 3e 69 46 72 65 65 20 2b 3d    pCsr->iFree +=
166f0 20 32 3b 0a 20 20 20 20 20 20 20 20 69 2d 2d 3b   2;.        i--;
16700 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
16710 20 20 20 70 43 73 72 2d 3e 69 46 72 65 65 20 2b     pCsr->iFree +
16720 3d 20 32 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74  = 2;.  }.}..stat
16730 69 63 20 69 6e 74 20 6d 75 6c 74 69 43 75 72 73  ic int multiCurs
16740 6f 72 41 64 76 61 6e 63 65 28 4d 75 6c 74 69 43  orAdvance(MultiC
16750 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74  ursor *pCsr, int
16760 20 62 52 65 76 65 72 73 65 29 7b 0a 20 20 69 6e   bReverse){.  in
16770 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20  t rc = LSM_OK;  
16780 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
16790 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a   Return Code */.
167a0 20 20 69 66 28 20 6c 73 6d 4d 43 75 72 73 6f 72    if( lsmMCursor
167b0 56 61 6c 69 64 28 70 43 73 72 29 20 29 7b 0a 20  Valid(pCsr) ){. 
167c0 20 20 20 64 6f 20 7b 0a 20 20 20 20 20 20 69 6e     do {.      in
167d0 74 20 69 4b 65 79 20 3d 20 70 43 73 72 2d 3e 61  t iKey = pCsr->a
167e0 54 72 65 65 5b 31 5d 3b 0a 0a 20 20 20 20 20 20  Tree[1];..      
167f0 61 73 73 65 72 74 43 75 72 73 6f 72 54 72 65 65  assertCursorTree
16800 28 70 43 73 72 29 3b 0a 0a 20 20 20 20 20 20 2f  (pCsr);..      /
16810 2a 20 49 66 20 74 68 69 73 20 6d 75 6c 74 69 2d  * If this multi-
16820 63 75 72 73 6f 72 20 69 73 20 61 64 76 61 6e 63  cursor is advanc
16830 69 6e 67 20 66 6f 72 77 61 72 64 73 2c 20 61 6e  ing forwards, an
16840 64 20 74 68 65 20 73 75 62 2d 63 75 72 73 6f 72  d the sub-cursor
16850 0a 20 20 20 20 20 20 2a 2a 20 62 65 69 6e 67 20  .      ** being 
16860 61 64 76 61 6e 63 65 64 20 69 73 20 74 68 65 20  advanced is the 
16870 6f 6e 65 20 74 68 61 74 20 73 65 70 61 72 61 74  one that separat
16880 6f 72 20 6b 65 79 73 20 6d 61 79 20 62 65 20 62  or keys may be b
16890 65 69 6e 67 20 72 65 61 64 0a 20 20 20 20 20 20  eing read.      
168a0 2a 2a 20 66 72 6f 6d 2c 20 72 65 63 6f 72 64 20  ** from, record 
168b0 74 68 65 20 63 75 72 72 65 6e 74 20 61 62 73 6f  the current abso
168c0 6c 75 74 65 20 70 6f 69 6e 74 65 72 20 76 61 6c  lute pointer val
168d0 75 65 2e 20 20 2a 2f 0a 20 20 20 20 20 20 69 66  ue.  */.      if
168e0 28 20 70 43 73 72 2d 3e 70 50 72 65 76 4d 65 72  ( pCsr->pPrevMer
168f0 67 65 50 74 72 20 29 7b 0a 20 20 20 20 20 20 20  gePtr ){.       
16900 20 69 66 28 20 69 4b 65 79 3d 3d 28 43 55 52 53   if( iKey==(CURS
16910 4f 52 5f 44 41 54 41 5f 53 45 47 4d 45 4e 54 2b  OR_DATA_SEGMENT+
16920 70 43 73 72 2d 3e 6e 50 74 72 29 20 29 7b 0a 20  pCsr->nPtr) ){. 
16930 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
16940 20 70 43 73 72 2d 3e 70 42 74 43 73 72 20 29 3b   pCsr->pBtCsr );
16950 0a 20 20 20 20 20 20 20 20 20 20 2a 70 43 73 72  .          *pCsr
16960 2d 3e 70 50 72 65 76 4d 65 72 67 65 50 74 72 20  ->pPrevMergePtr 
16970 3d 20 70 43 73 72 2d 3e 70 42 74 43 73 72 2d 3e  = pCsr->pBtCsr->
16980 69 50 74 72 3b 0a 20 20 20 20 20 20 20 20 7d 65  iPtr;.        }e
16990 6c 73 65 20 69 66 28 20 70 43 73 72 2d 3e 70 42  lse if( pCsr->pB
169a0 74 43 73 72 3d 3d 30 20 26 26 20 70 43 73 72 2d  tCsr==0 && pCsr-
169b0 3e 6e 50 74 72 3e 30 0a 20 20 20 20 20 20 20 20  >nPtr>0.        
169c0 20 20 20 20 20 20 20 26 26 20 69 4b 65 79 3d 3d         && iKey==
169d0 28 43 55 52 53 4f 52 5f 44 41 54 41 5f 53 45 47  (CURSOR_DATA_SEG
169e0 4d 45 4e 54 2b 70 43 73 72 2d 3e 6e 50 74 72 2d  MENT+pCsr->nPtr-
169f0 31 29 20 0a 20 20 20 20 20 20 20 20 29 7b 0a 20  1) .        ){. 
16a00 20 20 20 20 20 20 20 20 20 53 65 67 6d 65 6e 74           Segment
16a10 50 74 72 20 2a 70 50 74 72 20 3d 20 26 70 43 73  Ptr *pPtr = &pCs
16a20 72 2d 3e 61 50 74 72 5b 69 4b 65 79 2d 43 55 52  r->aPtr[iKey-CUR
16a30 53 4f 52 5f 44 41 54 41 5f 53 45 47 4d 45 4e 54  SOR_DATA_SEGMENT
16a40 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 2a 70 43  ];.          *pC
16a50 73 72 2d 3e 70 50 72 65 76 4d 65 72 67 65 50 74  sr->pPrevMergePt
16a60 72 20 3d 20 70 50 74 72 2d 3e 69 50 74 72 2b 70  r = pPtr->iPtr+p
16a70 50 74 72 2d 3e 69 50 67 50 74 72 3b 0a 20 20 20  Ptr->iPgPtr;.   
16a80 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a       }.      }..
16a90 20 20 20 20 20 20 69 66 28 20 69 4b 65 79 3d 3d        if( iKey==
16aa0 43 55 52 53 4f 52 5f 44 41 54 41 5f 54 52 45 45  CURSOR_DATA_TREE
16ab0 30 20 7c 7c 20 69 4b 65 79 3d 3d 43 55 52 53 4f  0 || iKey==CURSO
16ac0 52 5f 44 41 54 41 5f 54 52 45 45 31 20 29 7b 0a  R_DATA_TREE1 ){.
16ad0 20 20 20 20 20 20 20 20 54 72 65 65 43 75 72 73          TreeCurs
16ae0 6f 72 20 2a 70 54 72 65 65 43 73 72 20 3d 20 70  or *pTreeCsr = p
16af0 43 73 72 2d 3e 61 70 54 72 65 65 43 73 72 5b 69  Csr->apTreeCsr[i
16b00 4b 65 79 2d 43 55 52 53 4f 52 5f 44 41 54 41 5f  Key-CURSOR_DATA_
16b10 54 52 45 45 30 5d 3b 0a 20 20 20 20 20 20 20 20  TREE0];.        
16b20 69 66 28 20 62 52 65 76 65 72 73 65 20 29 7b 0a  if( bReverse ){.
16b30 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 6c            rc = l
16b40 73 6d 54 72 65 65 43 75 72 73 6f 72 50 72 65 76  smTreeCursorPrev
16b50 28 70 54 72 65 65 43 73 72 29 3b 0a 20 20 20 20  (pTreeCsr);.    
16b60 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
16b70 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 54 72 65       rc = lsmTre
16b80 65 43 75 72 73 6f 72 4e 65 78 74 28 70 54 72 65  eCursorNext(pTre
16b90 65 43 73 72 29 3b 0a 20 20 20 20 20 20 20 20 7d  eCsr);.        }
16ba0 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28  .      }else if(
16bb0 20 69 4b 65 79 3d 3d 43 55 52 53 4f 52 5f 44 41   iKey==CURSOR_DA
16bc0 54 41 5f 53 59 53 54 45 4d 20 29 7b 0a 20 20 20  TA_SYSTEM ){.   
16bd0 20 20 20 20 20 61 73 73 65 72 74 28 20 70 43 73       assert( pCs
16be0 72 2d 3e 66 6c 61 67 73 20 26 20 43 55 52 53 4f  r->flags & CURSO
16bf0 52 5f 46 4c 55 53 48 5f 46 52 45 45 4c 49 53 54  R_FLUSH_FREELIST
16c00 20 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65   );.        asse
16c10 72 74 28 20 62 52 65 76 65 72 73 65 3d 3d 30 20  rt( bReverse==0 
16c20 29 3b 0a 20 20 20 20 20 20 20 20 66 6c 43 73 72  );.        flCsr
16c30 41 64 76 61 6e 63 65 28 70 43 73 72 29 3b 0a 20  Advance(pCsr);. 
16c40 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 69       }else if( i
16c50 4b 65 79 3d 3d 28 43 55 52 53 4f 52 5f 44 41 54  Key==(CURSOR_DAT
16c60 41 5f 53 45 47 4d 45 4e 54 2b 70 43 73 72 2d 3e  A_SEGMENT+pCsr->
16c70 6e 50 74 72 29 20 29 7b 0a 20 20 20 20 20 20 20  nPtr) ){.       
16c80 20 61 73 73 65 72 74 28 20 62 52 65 76 65 72 73   assert( bRevers
16c90 65 3d 3d 30 20 26 26 20 70 43 73 72 2d 3e 70 42  e==0 && pCsr->pB
16ca0 74 43 73 72 20 29 3b 0a 20 20 20 20 20 20 20 20  tCsr );.        
16cb0 72 63 20 3d 20 62 74 72 65 65 43 75 72 73 6f 72  rc = btreeCursor
16cc0 4e 65 78 74 28 70 43 73 72 2d 3e 70 42 74 43 73  Next(pCsr->pBtCs
16cd0 72 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  r);.      }else{
16ce0 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65  .        rc = se
16cf0 67 6d 65 6e 74 43 75 72 73 6f 72 41 64 76 61 6e  gmentCursorAdvan
16d00 63 65 28 70 43 73 72 2c 20 69 4b 65 79 2d 43 55  ce(pCsr, iKey-CU
16d10 52 53 4f 52 5f 44 41 54 41 5f 53 45 47 4d 45 4e  RSOR_DATA_SEGMEN
16d20 54 2c 20 62 52 65 76 65 72 73 65 29 3b 0a 20 20  T, bReverse);.  
16d30 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
16d40 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20  rc==LSM_OK ){.  
16d50 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20        int i;.   
16d60 20 20 20 20 20 66 6f 72 28 69 3d 28 69 4b 65 79       for(i=(iKey
16d70 2b 70 43 73 72 2d 3e 6e 54 72 65 65 29 2f 32 3b  +pCsr->nTree)/2;
16d80 20 69 3e 30 3b 20 69 3d 69 2f 32 29 7b 0a 20 20   i>0; i=i/2){.  
16d90 20 20 20 20 20 20 20 20 6d 75 6c 74 69 43 75 72          multiCur
16da0 73 6f 72 44 6f 43 6f 6d 70 61 72 65 28 70 43 73  sorDoCompare(pCs
16db0 72 2c 20 69 2c 20 62 52 65 76 65 72 73 65 29 3b  r, i, bReverse);
16dc0 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
16dd0 20 20 20 61 73 73 65 72 74 43 75 72 73 6f 72 54     assertCursorT
16de0 72 65 65 28 70 43 73 72 29 3b 0a 20 20 20 20 20  ree(pCsr);.     
16df0 20 7d 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 6d   }.    }while( m
16e00 63 75 72 73 6f 72 41 64 76 61 6e 63 65 4f 6b 28  cursorAdvanceOk(
16e10 70 43 73 72 2c 20 62 52 65 76 65 72 73 65 2c 20  pCsr, bReverse, 
16e20 26 72 63 29 3d 3d 30 20 29 3b 0a 20 20 7d 0a 20  &rc)==0 );.  }. 
16e30 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69   return rc;.}..i
16e40 6e 74 20 6c 73 6d 4d 43 75 72 73 6f 72 4e 65 78  nt lsmMCursorNex
16e50 74 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70  t(MultiCursor *p
16e60 43 73 72 29 7b 0a 20 20 69 66 28 20 28 70 43 73  Csr){.  if( (pCs
16e70 72 2d 3e 66 6c 61 67 73 20 26 20 43 55 52 53 4f  r->flags & CURSO
16e80 52 5f 4e 45 58 54 5f 4f 4b 29 3d 3d 30 20 29 20  R_NEXT_OK)==0 ) 
16e90 72 65 74 75 72 6e 20 4c 53 4d 5f 4d 49 53 55 53  return LSM_MISUS
16ea0 45 5f 42 4b 50 54 3b 0a 20 20 72 65 74 75 72 6e  E_BKPT;.  return
16eb0 20 6d 75 6c 74 69 43 75 72 73 6f 72 41 64 76 61   multiCursorAdva
16ec0 6e 63 65 28 70 43 73 72 2c 20 30 29 3b 0a 7d 0a  nce(pCsr, 0);.}.
16ed0 0a 69 6e 74 20 6c 73 6d 4d 43 75 72 73 6f 72 50  .int lsmMCursorP
16ee0 72 65 76 28 4d 75 6c 74 69 43 75 72 73 6f 72 20  rev(MultiCursor 
16ef0 2a 70 43 73 72 29 7b 0a 20 20 69 66 28 20 28 70  *pCsr){.  if( (p
16f00 43 73 72 2d 3e 66 6c 61 67 73 20 26 20 43 55 52  Csr->flags & CUR
16f10 53 4f 52 5f 50 52 45 56 5f 4f 4b 29 3d 3d 30 20  SOR_PREV_OK)==0 
16f20 29 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4d 49 53  ) return LSM_MIS
16f30 55 53 45 5f 42 4b 50 54 3b 0a 20 20 72 65 74 75  USE_BKPT;.  retu
16f40 72 6e 20 6d 75 6c 74 69 43 75 72 73 6f 72 41 64  rn multiCursorAd
16f50 76 61 6e 63 65 28 70 43 73 72 2c 20 31 29 3b 0a  vance(pCsr, 1);.
16f60 7d 0a 0a 69 6e 74 20 6c 73 6d 4d 43 75 72 73 6f  }..int lsmMCurso
16f70 72 4b 65 79 28 4d 75 6c 74 69 43 75 72 73 6f 72  rKey(MultiCursor
16f80 20 2a 70 43 73 72 2c 20 76 6f 69 64 20 2a 2a 70   *pCsr, void **p
16f90 70 4b 65 79 2c 20 69 6e 74 20 2a 70 6e 4b 65 79  pKey, int *pnKey
16fa0 29 7b 0a 20 20 69 66 28 20 28 70 43 73 72 2d 3e  ){.  if( (pCsr->
16fb0 66 6c 61 67 73 20 26 20 43 55 52 53 4f 52 5f 53  flags & CURSOR_S
16fc0 45 45 4b 5f 45 51 29 20 7c 7c 20 70 43 73 72 2d  EEK_EQ) || pCsr-
16fd0 3e 61 54 72 65 65 3d 3d 30 20 29 7b 0a 20 20 20  >aTree==0 ){.   
16fe0 20 2a 70 6e 4b 65 79 20 3d 20 70 43 73 72 2d 3e   *pnKey = pCsr->
16ff0 6b 65 79 2e 6e 44 61 74 61 3b 0a 20 20 20 20 2a  key.nData;.    *
17000 70 70 4b 65 79 20 3d 20 70 43 73 72 2d 3e 6b 65  ppKey = pCsr->ke
17010 79 2e 70 44 61 74 61 3b 0a 20 20 7d 65 6c 73 65  y.pData;.  }else
17020 7b 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 20 3d  {.    int iKey =
17030 20 70 43 73 72 2d 3e 61 54 72 65 65 5b 31 5d 3b   pCsr->aTree[1];
17040 0a 0a 20 20 20 20 69 66 28 20 69 4b 65 79 3d 3d  ..    if( iKey==
17050 43 55 52 53 4f 52 5f 44 41 54 41 5f 54 52 45 45  CURSOR_DATA_TREE
17060 30 20 7c 7c 20 69 4b 65 79 3d 3d 43 55 52 53 4f  0 || iKey==CURSO
17070 52 5f 44 41 54 41 5f 54 52 45 45 31 20 29 7b 0a  R_DATA_TREE1 ){.
17080 20 20 20 20 20 20 54 72 65 65 43 75 72 73 6f 72        TreeCursor
17090 20 2a 70 54 72 65 65 43 73 72 20 3d 20 70 43 73   *pTreeCsr = pCs
170a0 72 2d 3e 61 70 54 72 65 65 43 73 72 5b 69 4b 65  r->apTreeCsr[iKe
170b0 79 2d 43 55 52 53 4f 52 5f 44 41 54 41 5f 54 52  y-CURSOR_DATA_TR
170c0 45 45 30 5d 3b 0a 20 20 20 20 20 20 6c 73 6d 54  EE0];.      lsmT
170d0 72 65 65 43 75 72 73 6f 72 4b 65 79 28 70 54 72  reeCursorKey(pTr
170e0 65 65 43 73 72 2c 20 30 2c 20 70 70 4b 65 79 2c  eeCsr, 0, ppKey,
170f0 20 70 6e 4b 65 79 29 3b 0a 20 20 20 20 7d 65 6c   pnKey);.    }el
17100 73 65 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4b  se{.      int nK
17110 65 79 3b 0a 0a 23 69 66 6e 64 65 66 20 4e 44 45  ey;..#ifndef NDE
17120 42 55 47 0a 20 20 20 20 20 20 76 6f 69 64 20 2a  BUG.      void *
17130 70 4b 65 79 3b 0a 20 20 20 20 20 20 69 6e 74 20  pKey;.      int 
17140 65 54 79 70 65 3b 0a 20 20 20 20 20 20 6d 75 6c  eType;.      mul
17150 74 69 43 75 72 73 6f 72 47 65 74 4b 65 79 28 70  tiCursorGetKey(p
17160 43 73 72 2c 20 69 4b 65 79 2c 20 26 65 54 79 70  Csr, iKey, &eTyp
17170 65 2c 20 26 70 4b 65 79 2c 20 26 6e 4b 65 79 29  e, &pKey, &nKey)
17180 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
17190 65 54 79 70 65 3d 3d 70 43 73 72 2d 3e 65 54 79  eType==pCsr->eTy
171a0 70 65 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65  pe );.      asse
171b0 72 74 28 20 6e 4b 65 79 3d 3d 70 43 73 72 2d 3e  rt( nKey==pCsr->
171c0 6b 65 79 2e 6e 44 61 74 61 20 29 3b 0a 20 20 20  key.nData );.   
171d0 20 20 20 61 73 73 65 72 74 28 20 6d 65 6d 63 6d     assert( memcm
171e0 70 28 70 4b 65 79 2c 20 70 43 73 72 2d 3e 6b 65  p(pKey, pCsr->ke
171f0 79 2e 70 44 61 74 61 2c 20 6e 4b 65 79 29 3d 3d  y.pData, nKey)==
17200 30 20 29 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 20  0 );.#endif..   
17210 20 20 20 6e 4b 65 79 20 3d 20 70 43 73 72 2d 3e     nKey = pCsr->
17220 6b 65 79 2e 6e 44 61 74 61 3b 0a 20 20 20 20 20  key.nData;.     
17230 20 69 66 28 20 6e 4b 65 79 3d 3d 30 20 29 7b 0a   if( nKey==0 ){.
17240 20 20 20 20 20 20 20 20 2a 70 70 4b 65 79 20 3d          *ppKey =
17250 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b   0;.      }else{
17260 0a 20 20 20 20 20 20 20 20 2a 70 70 4b 65 79 20  .        *ppKey 
17270 3d 20 70 43 73 72 2d 3e 6b 65 79 2e 70 44 61 74  = pCsr->key.pDat
17280 61 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  a;.      }.     
17290 20 2a 70 6e 4b 65 79 20 3d 20 6e 4b 65 79 3b 20   *pnKey = nKey; 
172a0 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
172b0 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 7d 0a 0a 2f  urn LSM_OK;.}../
172c0 2a 0a 2a 2a 20 43 6f 6d 70 61 72 65 20 74 68 65  *.** Compare the
172d0 20 63 75 72 72 65 6e 74 20 6b 65 79 20 74 68 61   current key tha
172e0 74 20 63 75 72 73 6f 72 20 63 73 72 20 70 6f 69  t cursor csr poi
172f0 6e 74 73 20 74 6f 20 77 69 74 68 20 70 4b 65 79  nts to with pKey
17300 2f 6e 4b 65 79 2e 20 53 65 74 0a 2a 2a 20 2a 70  /nKey. Set.** *p
17310 69 52 65 73 20 74 6f 20 74 68 65 20 72 65 73 75  iRes to the resu
17320 6c 74 20 61 6e 64 20 72 65 74 75 72 6e 20 4c 53  lt and return LS
17330 4d 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20 6c 73 6d  M_OK..*/.int lsm
17340 5f 63 73 72 5f 63 6d 70 28 6c 73 6d 5f 63 75 72  _csr_cmp(lsm_cur
17350 73 6f 72 20 2a 63 73 72 2c 20 63 6f 6e 73 74 20  sor *csr, const 
17360 76 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20  void *pKey, int 
17370 6e 4b 65 79 2c 20 69 6e 74 20 2a 70 69 52 65 73  nKey, int *piRes
17380 29 7b 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72  ){.  MultiCursor
17390 20 2a 70 43 73 72 20 3d 20 28 4d 75 6c 74 69 43   *pCsr = (MultiC
173a0 75 72 73 6f 72 20 2a 29 63 73 72 3b 0a 20 20 76  ursor *)csr;.  v
173b0 6f 69 64 20 2a 70 43 73 72 6b 65 79 3b 20 69 6e  oid *pCsrkey; in
173c0 74 20 6e 43 73 72 6b 65 79 3b 0a 20 20 69 6e 74  t nCsrkey;.  int
173d0 20 72 63 3b 0a 20 20 72 63 20 3d 20 6c 73 6d 4d   rc;.  rc = lsmM
173e0 43 75 72 73 6f 72 4b 65 79 28 70 43 73 72 2c 20  CursorKey(pCsr, 
173f0 26 70 43 73 72 6b 65 79 2c 20 26 6e 43 73 72 6b  &pCsrkey, &nCsrk
17400 65 79 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 4c  ey);.  if( rc==L
17410 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74  SM_OK ){.    int
17420 20 28 2a 78 43 6d 70 29 28 76 6f 69 64 20 2a 2c   (*xCmp)(void *,
17430 20 69 6e 74 2c 20 76 6f 69 64 20 2a 2c 20 69 6e   int, void *, in
17440 74 29 20 3d 20 70 43 73 72 2d 3e 70 44 62 2d 3e  t) = pCsr->pDb->
17450 78 43 6d 70 3b 0a 20 20 20 20 2a 70 69 52 65 73  xCmp;.    *piRes
17460 20 3d 20 73 6f 72 74 65 64 4b 65 79 43 6f 6d 70   = sortedKeyComp
17470 61 72 65 28 78 43 6d 70 2c 20 30 2c 20 70 43 73  are(xCmp, 0, pCs
17480 72 6b 65 79 2c 20 6e 43 73 72 6b 65 79 2c 20 30  rkey, nCsrkey, 0
17490 2c 20 28 76 6f 69 64 20 2a 29 70 4b 65 79 2c 20  , (void *)pKey, 
174a0 6e 4b 65 79 29 3b 0a 20 20 7d 0a 20 20 72 65 74  nKey);.  }.  ret
174b0 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20 6c  urn rc;.}..int l
174c0 73 6d 4d 43 75 72 73 6f 72 56 61 6c 75 65 28 4d  smMCursorValue(M
174d0 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72  ultiCursor *pCsr
174e0 2c 20 76 6f 69 64 20 2a 2a 70 70 56 61 6c 2c 20  , void **ppVal, 
174f0 69 6e 74 20 2a 70 6e 56 61 6c 29 7b 0a 20 20 76  int *pnVal){.  v
17500 6f 69 64 20 2a 70 56 61 6c 3b 0a 20 20 69 6e 74  oid *pVal;.  int
17510 20 6e 56 61 6c 3b 0a 20 20 69 6e 74 20 72 63 3b   nVal;.  int rc;
17520 0a 20 20 69 66 28 20 28 70 43 73 72 2d 3e 66 6c  .  if( (pCsr->fl
17530 61 67 73 20 26 20 43 55 52 53 4f 52 5f 53 45 45  ags & CURSOR_SEE
17540 4b 5f 45 51 29 20 7c 7c 20 70 43 73 72 2d 3e 61  K_EQ) || pCsr->a
17550 54 72 65 65 3d 3d 30 20 29 7b 0a 20 20 20 20 72  Tree==0 ){.    r
17560 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 20 20  c = LSM_OK;.    
17570 6e 56 61 6c 20 3d 20 70 43 73 72 2d 3e 76 61 6c  nVal = pCsr->val
17580 2e 6e 44 61 74 61 3b 0a 20 20 20 20 70 56 61 6c  .nData;.    pVal
17590 20 3d 20 70 43 73 72 2d 3e 76 61 6c 2e 70 44 61   = pCsr->val.pDa
175a0 74 61 3b 0a 20 20 7d 65 6c 73 65 7b 0a 0a 20 20  ta;.  }else{..  
175b0 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
175c0 61 54 72 65 65 20 29 3b 0a 20 20 20 20 61 73 73  aTree );.    ass
175d0 65 72 74 28 20 6d 63 75 72 73 6f 72 4c 6f 63 61  ert( mcursorLoca
175e0 74 69 6f 6e 4f 6b 28 70 43 73 72 2c 20 28 70 43  tionOk(pCsr, (pC
175f0 73 72 2d 3e 66 6c 61 67 73 20 26 20 43 55 52 53  sr->flags & CURS
17600 4f 52 5f 49 47 4e 4f 52 45 5f 44 45 4c 45 54 45  OR_IGNORE_DELETE
17610 29 29 20 29 3b 0a 0a 20 20 20 20 72 63 20 3d 20  )) );..    rc = 
17620 6d 75 6c 74 69 43 75 72 73 6f 72 47 65 74 56 61  multiCursorGetVa
17630 6c 28 70 43 73 72 2c 20 70 43 73 72 2d 3e 61 54  l(pCsr, pCsr->aT
17640 72 65 65 5b 31 5d 2c 20 26 70 56 61 6c 2c 20 26  ree[1], &pVal, &
17650 6e 56 61 6c 29 3b 0a 20 20 20 20 69 66 28 20 70  nVal);.    if( p
17660 56 61 6c 20 26 26 20 72 63 3d 3d 4c 53 4d 5f 4f  Val && rc==LSM_O
17670 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  K ){.      rc = 
17680 73 6f 72 74 65 64 42 6c 6f 62 53 65 74 28 70 43  sortedBlobSet(pC
17690 73 72 2d 3e 70 44 62 2d 3e 70 45 6e 76 2c 20 26  sr->pDb->pEnv, &
176a0 70 43 73 72 2d 3e 76 61 6c 2c 20 70 56 61 6c 2c  pCsr->val, pVal,
176b0 20 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 70 56   nVal);.      pV
176c0 61 6c 20 3d 20 70 43 73 72 2d 3e 76 61 6c 2e 70  al = pCsr->val.p
176d0 44 61 74 61 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  Data;.    }..   
176e0 20 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20   if( rc!=LSM_OK 
176f0 29 7b 0a 20 20 20 20 20 20 70 56 61 6c 20 3d 20  ){.      pVal = 
17700 30 3b 0a 20 20 20 20 20 20 6e 56 61 6c 20 3d 20  0;.      nVal = 
17710 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a  0;.    }.  }.  *
17720 70 70 56 61 6c 20 3d 20 70 56 61 6c 3b 0a 20 20  ppVal = pVal;.  
17730 2a 70 6e 56 61 6c 20 3d 20 6e 56 61 6c 3b 0a 20  *pnVal = nVal;. 
17740 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69   return rc;.}..i
17750 6e 74 20 6c 73 6d 4d 43 75 72 73 6f 72 54 79 70  nt lsmMCursorTyp
17760 65 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70  e(MultiCursor *p
17770 43 73 72 2c 20 69 6e 74 20 2a 70 65 54 79 70 65  Csr, int *peType
17780 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 43 73  ){.  assert( pCs
17790 72 2d 3e 61 54 72 65 65 20 29 3b 0a 20 20 6d 75  r->aTree );.  mu
177a0 6c 74 69 43 75 72 73 6f 72 47 65 74 4b 65 79 28  ltiCursorGetKey(
177b0 70 43 73 72 2c 20 70 43 73 72 2d 3e 61 54 72 65  pCsr, pCsr->aTre
177c0 65 5b 31 5d 2c 20 70 65 54 79 70 65 2c 20 30 2c  e[1], peType, 0,
177d0 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 4c 53   0);.  return LS
177e0 4d 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42  M_OK;.}../*.** B
177f0 75 66 66 65 72 20 61 44 61 74 61 5b 5d 2c 20 73  uffer aData[], s
17800 69 7a 65 20 6e 44 61 74 61 2c 20 69 73 20 61 73  ize nData, is as
17810 73 75 6d 65 64 20 74 6f 20 63 6f 6e 74 61 69 6e  sumed to contain
17820 20 61 20 76 61 6c 69 64 20 62 2d 74 72 65 65 20   a valid b-tree 
17830 0a 2a 2a 20 68 69 65 72 61 72 63 68 79 20 70 61  .** hierarchy pa
17840 67 65 20 69 6d 61 67 65 2e 20 52 65 74 75 72 6e  ge image. Return
17850 20 74 68 65 20 6f 66 66 73 65 74 20 69 6e 20 61   the offset in a
17860 44 61 74 61 5b 5d 20 6f 66 20 74 68 65 20 6e 65  Data[] of the ne
17870 78 74 20 66 72 65 65 0a 2a 2a 20 62 79 74 65 20  xt free.** byte 
17880 69 6e 20 74 68 65 20 64 61 74 61 20 61 72 65 61  in the data area
17890 20 28 77 68 65 72 65 20 61 20 6e 65 77 20 63 65   (where a new ce
178a0 6c 6c 20 6d 61 79 20 62 65 20 77 72 69 74 74 65  ll may be writte
178b0 6e 20 69 66 20 74 68 65 72 65 20 69 73 0a 2a 2a  n if there is.**
178c0 20 73 70 61 63 65 29 2e 0a 2a 2f 0a 73 74 61 74   space)..*/.stat
178d0 69 63 20 69 6e 74 20 6d 65 72 67 65 57 6f 72 6b  ic int mergeWork
178e0 65 72 50 61 67 65 4f 66 66 73 65 74 28 75 38 20  erPageOffset(u8 
178f0 2a 61 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74  *aData, int nDat
17900 61 29 7b 0a 20 20 69 6e 74 20 6e 52 65 63 3b 0a  a){.  int nRec;.
17910 20 20 69 6e 74 20 69 4f 66 66 3b 0a 20 20 69 6e    int iOff;.  in
17920 74 20 6e 4b 65 79 3b 0a 20 20 69 6e 74 20 65 54  t nKey;.  int eT
17930 79 70 65 3b 0a 0a 20 20 6e 52 65 63 20 3d 20 6c  ype;..  nRec = l
17940 73 6d 47 65 74 55 31 36 28 26 61 44 61 74 61 5b  smGetU16(&aData[
17950 53 45 47 4d 45 4e 54 5f 4e 52 45 43 4f 52 44 5f  SEGMENT_NRECORD_
17960 4f 46 46 53 45 54 28 6e 44 61 74 61 29 5d 29 3b  OFFSET(nData)]);
17970 0a 20 20 69 4f 66 66 20 3d 20 6c 73 6d 47 65 74  .  iOff = lsmGet
17980 55 31 36 28 26 61 44 61 74 61 5b 53 45 47 4d 45  U16(&aData[SEGME
17990 4e 54 5f 43 45 4c 4c 50 54 52 5f 4f 46 46 53 45  NT_CELLPTR_OFFSE
179a0 54 28 6e 44 61 74 61 2c 20 6e 52 65 63 2d 31 29  T(nData, nRec-1)
179b0 5d 29 3b 0a 20 20 65 54 79 70 65 20 3d 20 61 44  ]);.  eType = aD
179c0 61 74 61 5b 69 4f 66 66 2b 2b 5d 3b 0a 20 20 61  ata[iOff++];.  a
179d0 73 73 65 72 74 28 20 65 54 79 70 65 3d 3d 30 20  ssert( eType==0 
179e0 0a 20 20 20 20 20 20 20 7c 7c 20 65 54 79 70 65  .       || eType
179f0 3d 3d 28 4c 53 4d 5f 53 59 53 54 45 4d 4b 45 59  ==(LSM_SYSTEMKEY
17a00 7c 4c 53 4d 5f 53 45 50 41 52 41 54 4f 52 29 20  |LSM_SEPARATOR) 
17a10 0a 20 20 20 20 20 20 20 7c 7c 20 65 54 79 70 65  .       || eType
17a20 3d 3d 28 4c 53 4d 5f 53 45 50 41 52 41 54 4f 52  ==(LSM_SEPARATOR
17a30 29 0a 20 20 29 3b 0a 0a 20 20 69 4f 66 66 20 2b  ).  );..  iOff +
17a40 3d 20 6c 73 6d 56 61 72 69 6e 74 47 65 74 33 32  = lsmVarintGet32
17a50 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c 20 26  (&aData[iOff], &
17a60 6e 4b 65 79 29 3b 0a 20 20 69 4f 66 66 20 2b 3d  nKey);.  iOff +=
17a70 20 6c 73 6d 56 61 72 69 6e 74 47 65 74 33 32 28   lsmVarintGet32(
17a80 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c 20 26 6e  &aData[iOff], &n
17a90 4b 65 79 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20  Key);..  return 
17aa0 69 4f 66 66 20 2b 20 28 65 54 79 70 65 20 3f 20  iOff + (eType ? 
17ab0 6e 4b 65 79 20 3a 20 30 29 3b 0a 7d 0a 0a 2f 2a  nKey : 0);.}../*
17ac0 0a 2a 2a 20 46 6f 6c 6c 6f 77 69 6e 67 20 61 20  .** Following a 
17ad0 63 68 65 63 6b 70 6f 69 6e 74 20 6f 70 65 72 61  checkpoint opera
17ae0 74 69 6f 6e 2c 20 64 61 74 61 62 61 73 65 20 70  tion, database p
17af0 61 67 65 73 20 74 68 61 74 20 61 72 65 20 70 61  ages that are pa
17b00 72 74 20 6f 66 20 74 68 65 0a 2a 2a 20 63 68 65  rt of the.** che
17b10 63 6b 70 6f 69 6e 74 65 64 20 73 74 61 74 65 20  ckpointed state 
17b20 6f 66 20 74 68 65 20 4c 53 4d 20 61 72 65 20 64  of the LSM are d
17b30 65 65 6d 65 64 20 72 65 61 64 2d 6f 6e 6c 79 2e  eemed read-only.
17b40 20 54 68 69 73 20 69 6e 63 6c 75 64 65 73 20 74   This includes t
17b50 68 65 0a 2a 2a 20 72 69 67 68 74 2d 6d 6f 73 74  he.** right-most
17b60 20 70 61 67 65 20 6f 66 20 74 68 65 20 62 2d 74   page of the b-t
17b70 72 65 65 20 68 69 65 72 61 72 63 68 79 20 6f 66  ree hierarchy of
17b80 20 61 6e 79 20 73 65 70 61 72 61 74 6f 72 73 20   any separators 
17b90 61 72 72 61 79 20 75 6e 64 65 72 0a 2a 2a 20 63  array under.** c
17ba0 6f 6e 73 74 72 75 63 74 69 6f 6e 2c 20 61 6e 64  onstruction, and
17bb0 20 61 6c 6c 20 70 61 67 65 73 20 62 65 74 77 65   all pages betwe
17bc0 65 6e 20 69 74 20 61 6e 64 20 74 68 65 20 62 2d  en it and the b-
17bd0 74 72 65 65 20 72 6f 6f 74 2c 20 69 6e 63 6c 75  tree root, inclu
17be0 73 69 76 65 2e 0a 2a 2a 20 54 68 69 73 20 69 73  sive..** This is
17bf0 20 61 20 70 72 6f 62 6c 65 6d 2c 20 61 73 20 77   a problem, as w
17c00 68 65 6e 20 66 75 72 74 68 65 72 20 70 61 67 65  hen further page
17c10 73 20 61 72 65 20 61 70 70 65 6e 64 65 64 20 74  s are appended t
17c20 6f 20 74 68 65 20 73 65 70 61 72 61 74 6f 72 73  o the separators
17c30 0a 2a 2a 20 61 72 72 61 79 2c 20 65 6e 74 72 69  .** array, entri
17c40 65 73 20 6d 75 73 74 20 62 65 20 61 64 64 65 64  es must be added
17c50 20 74 6f 20 74 68 65 20 69 6e 64 69 63 61 74 65   to the indicate
17c60 64 20 62 2d 74 72 65 65 20 68 69 65 72 61 72 63  d b-tree hierarc
17c70 68 79 20 70 61 67 65 73 2e 0a 2a 2a 0a 2a 2a 20  hy pages..**.** 
17c80 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 63 6f  This function co
17c90 70 69 65 73 20 61 6c 6c 20 73 75 63 68 20 62 2d  pies all such b-
17ca0 74 72 65 65 20 70 61 67 65 73 20 74 6f 20 6e 65  tree pages to ne
17cb0 77 20 6c 6f 63 61 74 69 6f 6e 73 2c 20 73 6f 20  w locations, so 
17cc0 74 68 61 74 0a 2a 2a 20 74 68 65 79 20 63 61 6e  that.** they can
17cd0 20 62 65 20 6d 6f 64 69 66 69 65 64 20 61 73 20   be modified as 
17ce0 72 65 71 75 69 72 65 64 2e 0a 2a 2a 0a 2a 2a 20  required..**.** 
17cf0 54 68 65 20 63 6f 6d 70 6c 69 63 61 74 69 6f 6e  The complication
17d00 20 69 73 20 74 68 61 74 20 6e 6f 74 20 61 6c 6c   is that not all
17d10 20 64 61 74 61 62 61 73 65 20 70 61 67 65 73 20   database pages 
17d20 61 72 65 20 74 68 65 20 73 61 6d 65 20 73 69 7a  are the same siz
17d30 65 20 2d 20 64 75 65 0a 2a 2a 20 74 6f 20 74 68  e - due.** to th
17d40 65 20 77 61 79 20 74 68 65 20 66 69 6c 65 2e 63  e way the file.c
17d50 20 6d 6f 64 75 6c 65 20 77 6f 72 6b 73 20 73 6f   module works so
17d60 6d 65 20 28 74 68 65 20 66 69 72 73 74 20 61 6e  me (the first an
17d70 64 20 6c 61 73 74 20 69 6e 20 65 61 63 68 20 62  d last in each b
17d80 6c 6f 63 6b 29 0a 2a 2a 20 61 72 65 20 34 20 62  lock).** are 4 b
17d90 79 74 65 73 20 73 6d 61 6c 6c 65 72 20 74 68 61  ytes smaller tha
17da0 6e 20 74 68 65 20 6f 74 68 65 72 73 2e 0a 2a 2f  n the others..*/
17db0 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 72 67  .static int merg
17dc0 65 57 6f 72 6b 65 72 4d 6f 76 65 48 69 65 72 61  eWorkerMoveHiera
17dd0 72 63 68 79 28 0a 20 20 4d 65 72 67 65 57 6f 72  rchy(.  MergeWor
17de0 6b 65 72 20 2a 70 4d 57 2c 20 20 20 20 20 20 20  ker *pMW,       
17df0 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65          /* Merge
17e00 20 77 6f 72 6b 65 72 20 2a 2f 0a 20 20 69 6e 74   worker */.  int
17e10 20 62 53 65 70 20 20 20 20 20 20 20 20 20 20 20   bSep           
17e20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
17e30 54 72 75 65 20 66 6f 72 20 73 65 70 61 72 61 74  True for separat
17e40 6f 72 73 20 72 75 6e 20 2a 2f 0a 29 7b 0a 20 20  ors run */.){.  
17e50 6c 73 6d 5f 64 62 20 2a 70 44 62 20 3d 20 70 4d  lsm_db *pDb = pM
17e60 57 2d 3e 70 44 62 3b 20 20 20 20 20 20 20 20 20  W->pDb;         
17e70 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64  /* Database hand
17e80 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d  le */.  int rc =
17e90 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20   LSM_OK;        
17ea0 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
17eb0 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
17ec0 69 3b 0a 20 20 50 61 67 65 20 2a 2a 61 70 48 69  i;.  Page **apHi
17ed0 65 72 20 3d 20 70 4d 57 2d 3e 68 69 65 72 2e 61  er = pMW->hier.a
17ee0 70 48 69 65 72 3b 0a 20 20 69 6e 74 20 6e 48 69  pHier;.  int nHi
17ef0 65 72 20 3d 20 70 4d 57 2d 3e 68 69 65 72 2e 6e  er = pMW->hier.n
17f00 48 69 65 72 3b 0a 0a 20 20 66 6f 72 28 69 3d 30  Hier;..  for(i=0
17f10 3b 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20  ; rc==LSM_OK && 
17f20 69 3c 6e 48 69 65 72 3b 20 69 2b 2b 29 7b 0a 20  i<nHier; i++){. 
17f30 20 20 20 50 61 67 65 20 2a 70 4e 65 77 20 3d 20     Page *pNew = 
17f40 30 3b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 46  0;.    rc = lsmF
17f50 73 53 6f 72 74 65 64 41 70 70 65 6e 64 28 70 44  sSortedAppend(pD
17f60 62 2d 3e 70 46 53 2c 20 70 44 62 2d 3e 70 57 6f  b->pFS, pDb->pWo
17f70 72 6b 65 72 2c 20 70 4d 57 2d 3e 70 4c 65 76 65  rker, pMW->pLeve
17f80 6c 2c 20 31 2c 20 26 70 4e 65 77 29 3b 0a 20 20  l, 1, &pNew);.  
17f90 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 4c 53    assert( rc==LS
17fa0 4d 5f 4f 4b 20 29 3b 0a 0a 20 20 20 20 69 66 28  M_OK );..    if(
17fb0 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20   rc==LSM_OK ){. 
17fc0 20 20 20 20 20 75 38 20 2a 61 31 3b 20 69 6e 74       u8 *a1; int
17fd0 20 6e 31 3b 0a 20 20 20 20 20 20 75 38 20 2a 61   n1;.      u8 *a
17fe0 32 3b 20 69 6e 74 20 6e 32 3b 0a 0a 20 20 20 20  2; int n2;..    
17ff0 20 20 61 31 20 3d 20 66 73 50 61 67 65 44 61 74    a1 = fsPageDat
18000 61 28 70 4e 65 77 2c 20 26 6e 31 29 3b 0a 20 20  a(pNew, &n1);.  
18010 20 20 20 20 61 32 20 3d 20 66 73 50 61 67 65 44      a2 = fsPageD
18020 61 74 61 28 61 70 48 69 65 72 5b 69 5d 2c 20 26  ata(apHier[i], &
18030 6e 32 29 3b 0a 0a 20 20 20 20 20 20 61 73 73 65  n2);..      asse
18040 72 74 28 20 6e 31 3d 3d 6e 32 20 7c 7c 20 6e 31  rt( n1==n2 || n1
18050 2b 34 3d 3d 6e 32 20 29 3b 0a 0a 20 20 20 20 20  +4==n2 );..     
18060 20 69 66 28 20 6e 31 3d 3d 6e 32 20 29 7b 0a 20   if( n1==n2 ){. 
18070 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 61 31         memcpy(a1
18080 2c 20 61 32 2c 20 6e 32 29 3b 0a 20 20 20 20 20  , a2, n2);.     
18090 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
180a0 69 6e 74 20 6e 45 6e 74 72 79 20 3d 20 70 61 67  int nEntry = pag
180b0 65 47 65 74 4e 52 65 63 28 61 32 2c 20 6e 32 29  eGetNRec(a2, n2)
180c0 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 45  ;.        int iE
180d0 6f 66 31 20 3d 20 53 45 47 4d 45 4e 54 5f 45 4f  of1 = SEGMENT_EO
180e0 46 28 6e 31 2c 20 6e 45 6e 74 72 79 29 3b 0a 20  F(n1, nEntry);. 
180f0 20 20 20 20 20 20 20 69 6e 74 20 69 45 6f 66 32         int iEof2
18100 20 3d 20 53 45 47 4d 45 4e 54 5f 45 4f 46 28 6e   = SEGMENT_EOF(n
18110 32 2c 20 6e 45 6e 74 72 79 29 3b 0a 0a 20 20 20  2, nEntry);..   
18120 20 20 20 20 20 6d 65 6d 63 70 79 28 61 31 2c 20       memcpy(a1, 
18130 61 32 2c 20 69 45 6f 66 32 20 2d 20 34 29 3b 0a  a2, iEof2 - 4);.
18140 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26          memcpy(&
18150 61 31 5b 69 45 6f 66 31 5d 2c 20 26 61 32 5b 69  a1[iEof1], &a2[i
18160 45 6f 66 32 5d 2c 20 6e 32 20 2d 20 69 45 6f 66  Eof2], n2 - iEof
18170 32 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20  2);.      }..   
18180 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65     lsmFsPageRele
18190 61 73 65 28 61 70 48 69 65 72 5b 69 5d 29 3b 0a  ase(apHier[i]);.
181a0 20 20 20 20 20 20 61 70 48 69 65 72 5b 69 5d 20        apHier[i] 
181b0 3d 20 70 4e 65 77 3b 0a 0a 23 69 66 20 30 0a 20  = pNew;..#if 0. 
181c0 20 20 20 20 20 61 73 73 65 72 74 28 20 6e 31 3d       assert( n1=
181d0 3d 6e 32 20 7c 7c 20 6e 31 2b 34 3d 3d 6e 32 20  =n2 || n1+4==n2 
181e0 7c 7c 20 6e 32 2b 34 3d 3d 6e 31 20 29 3b 0a 20  || n2+4==n1 );. 
181f0 20 20 20 20 20 69 66 28 20 6e 31 3e 3d 6e 32 20       if( n1>=n2 
18200 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 49 66  ){.        /* If
18210 20 6e 31 20 28 73 69 7a 65 20 6f 66 20 74 68 65   n1 (size of the
18220 20 6e 65 77 20 70 61 67 65 29 20 69 73 20 65 71   new page) is eq
18230 75 61 6c 20 74 6f 20 6f 72 20 67 72 65 61 74 65  ual to or greate
18240 72 20 74 68 61 6e 20 6e 32 20 28 74 68 65 0a 20  r than n2 (the. 
18250 20 20 20 20 20 20 20 2a 2a 20 73 69 7a 65 20 6f         ** size o
18260 66 20 74 68 65 20 6f 6c 64 20 70 61 67 65 29 2c  f the old page),
18270 20 74 68 65 6e 20 63 6f 70 79 20 74 68 65 20 64   then copy the d
18280 61 74 61 20 69 6e 74 6f 20 74 68 65 20 6e 65 77  ata into the new
18290 20 70 61 67 65 2e 20 49 66 0a 20 20 20 20 20 20   page. If.      
182a0 20 20 2a 2a 20 6e 31 3d 3d 6e 32 2c 20 74 68 69    ** n1==n2, thi
182b0 73 20 63 6f 75 6c 64 20 62 65 20 64 6f 6e 65 20  s could be done 
182c0 77 69 74 68 20 61 20 73 69 6e 67 6c 65 20 6d 65  with a single me
182d0 6d 63 70 79 28 29 2e 20 48 6f 77 65 76 65 72 2c  mcpy(). However,
182e0 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 69 6e   .        ** sin
182f0 63 65 20 73 6f 6d 65 74 69 6d 65 73 20 6e 31 3e  ce sometimes n1>
18300 6e 32 2c 20 74 68 65 20 70 61 67 65 20 63 6f 6e  n2, the page con
18310 74 65 6e 74 20 61 6e 64 20 66 6f 6f 74 65 72 20  tent and footer 
18320 6d 75 73 74 20 62 65 20 63 6f 70 69 65 64 20 0a  must be copied .
18330 20 20 20 20 20 20 20 20 2a 2a 20 73 65 70 61 72          ** separ
18340 61 74 65 6c 79 2e 20 2a 2f 0a 20 20 20 20 20 20  ately. */.      
18350 20 20 69 6e 74 20 6e 45 6e 74 72 79 20 3d 20 70    int nEntry = p
18360 61 67 65 47 65 74 4e 52 65 63 28 61 32 2c 20 6e  ageGetNRec(a2, n
18370 32 29 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20  2);.        int 
18380 69 45 6f 66 31 20 3d 20 53 45 47 4d 45 4e 54 5f  iEof1 = SEGMENT_
18390 45 4f 46 28 6e 31 2c 20 6e 45 6e 74 72 79 29 3b  EOF(n1, nEntry);
183a0 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 45 6f  .        int iEo
183b0 66 32 20 3d 20 53 45 47 4d 45 4e 54 5f 45 4f 46  f2 = SEGMENT_EOF
183c0 28 6e 32 2c 20 6e 45 6e 74 72 79 29 3b 0a 20 20  (n2, nEntry);.  
183d0 20 20 20 20 20 20 6d 65 6d 63 70 79 28 61 31 2c        memcpy(a1,
183e0 20 61 32 2c 20 69 45 6f 66 32 29 3b 0a 20 20 20   a2, iEof2);.   
183f0 20 20 20 20 20 6d 65 6d 63 70 79 28 26 61 31 5b       memcpy(&a1[
18400 69 45 6f 66 31 5d 2c 20 26 61 32 5b 69 45 6f 66  iEof1], &a2[iEof
18410 32 5d 2c 20 6e 32 20 2d 20 69 45 6f 66 32 29 3b  2], n2 - iEof2);
18420 0a 20 20 20 20 20 20 20 20 6c 73 6d 46 73 50 61  .        lsmFsPa
18430 67 65 52 65 6c 65 61 73 65 28 61 70 48 69 65 72  geRelease(apHier
18440 5b 69 5d 29 3b 0a 20 20 20 20 20 20 20 20 61 70  [i]);.        ap
18450 48 69 65 72 5b 69 5d 20 3d 20 70 4e 65 77 3b 0a  Hier[i] = pNew;.
18460 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
18470 20 20 20 20 20 6c 73 6d 50 75 74 55 31 36 28 26       lsmPutU16(&
18480 61 31 5b 53 45 47 4d 45 4e 54 5f 46 4c 41 47 53  a1[SEGMENT_FLAGS
18490 5f 4f 46 46 53 45 54 28 6e 31 29 5d 2c 20 53 45  _OFFSET(n1)], SE
184a0 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47  GMENT_BTREE_FLAG
184b0 29 3b 0a 20 20 20 20 20 20 20 20 6c 73 6d 50 75  );.        lsmPu
184c0 74 55 31 36 28 26 61 31 5b 53 45 47 4d 45 4e 54  tU16(&a1[SEGMENT
184d0 5f 4e 52 45 43 4f 52 44 5f 4f 46 46 53 45 54 28  _NRECORD_OFFSET(
184e0 6e 31 29 5d 2c 20 30 29 3b 0a 20 20 20 20 20 20  n1)], 0);.      
184f0 20 20 6c 73 6d 50 75 74 55 36 34 28 26 61 31 5b    lsmPutU64(&a1[
18500 53 45 47 4d 45 4e 54 5f 50 4f 49 4e 54 45 52 5f  SEGMENT_POINTER_
18510 4f 46 46 53 45 54 28 6e 31 29 5d 2c 20 30 29 3b  OFFSET(n1)], 0);
18520 0a 20 20 20 20 20 20 20 20 69 20 3d 20 69 20 2d  .        i = i -
18530 20 31 3b 0a 20 20 20 20 20 20 20 20 6c 73 6d 46   1;.        lsmF
18540 73 50 61 67 65 52 65 6c 65 61 73 65 28 70 4e 65  sPageRelease(pNe
18550 77 29 3b 0a 20 20 20 20 20 20 7d 0a 23 65 6e 64  w);.      }.#end
18560 69 66 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 23 69  if.    }.  }..#i
18570 66 64 65 66 20 4c 53 4d 5f 44 45 42 55 47 0a 20  fdef LSM_DEBUG. 
18580 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
18590 29 7b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  ){.    for(i=0; 
185a0 69 3c 6e 48 69 65 72 3b 20 69 2b 2b 29 20 61 73  i<nHier; i++) as
185b0 73 65 72 74 28 20 6c 73 6d 46 73 50 61 67 65 57  sert( lsmFsPageW
185c0 72 69 74 61 62 6c 65 28 61 70 48 69 65 72 5b 69  ritable(apHier[i
185d0 5d 29 20 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66  ]) );.  }.#endif
185e0 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
185f0 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65  ../*.** Allocate
18600 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 20 74 68   and populate th
18610 65 20 4d 65 72 67 65 57 6f 72 6b 65 72 2e 61 70  e MergeWorker.ap
18620 48 69 65 72 5b 5d 20 61 72 72 61 79 2e 0a 2a 2f  Hier[] array..*/
18630 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 72 67  .static int merg
18640 65 57 6f 72 6b 65 72 4c 6f 61 64 48 69 65 72 61  eWorkerLoadHiera
18650 72 63 68 79 28 4d 65 72 67 65 57 6f 72 6b 65 72  rchy(MergeWorker
18660 20 2a 70 4d 57 29 7b 0a 20 20 69 6e 74 20 72 63   *pMW){.  int rc
18670 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 53 65 67   = LSM_OK;.  Seg
18680 6d 65 6e 74 20 2a 70 53 65 67 3b 0a 20 20 48 69  ment *pSeg;.  Hi
18690 65 72 61 72 63 68 79 20 2a 70 3b 0a 20 0a 20 20  erarchy *p;. .  
186a0 70 53 65 67 20 3d 20 26 70 4d 57 2d 3e 70 4c 65  pSeg = &pMW->pLe
186b0 76 65 6c 2d 3e 6c 68 73 3b 0a 20 20 70 20 3d 20  vel->lhs;.  p = 
186c0 26 70 4d 57 2d 3e 68 69 65 72 3b 0a 0a 20 20 69  &pMW->hier;..  i
186d0 66 28 20 70 2d 3e 61 70 48 69 65 72 3d 3d 30 20  f( p->apHier==0 
186e0 26 26 20 70 53 65 67 2d 3e 69 52 6f 6f 74 21 3d  && pSeg->iRoot!=
186f0 30 20 29 7b 0a 20 20 20 20 46 69 6c 65 53 79 73  0 ){.    FileSys
18700 74 65 6d 20 2a 70 46 53 20 3d 20 70 4d 57 2d 3e  tem *pFS = pMW->
18710 70 44 62 2d 3e 70 46 53 3b 0a 20 20 20 20 6c 73  pDb->pFS;.    ls
18720 6d 5f 65 6e 76 20 2a 70 45 6e 76 20 3d 20 70 4d  m_env *pEnv = pM
18730 57 2d 3e 70 44 62 2d 3e 70 45 6e 76 3b 0a 20 20  W->pDb->pEnv;.  
18740 20 20 50 61 67 65 20 2a 2a 61 70 48 69 65 72 20    Page **apHier 
18750 3d 20 30 3b 0a 20 20 20 20 69 6e 74 20 6e 48 69  = 0;.    int nHi
18760 65 72 20 3d 20 30 3b 0a 20 20 20 20 69 6e 74 20  er = 0;.    int 
18770 69 50 67 20 3d 20 70 53 65 67 2d 3e 69 52 6f 6f  iPg = pSeg->iRoo
18780 74 3b 0a 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20  t;..    do {.   
18790 20 20 20 50 61 67 65 20 2a 70 50 67 20 3d 20 30     Page *pPg = 0
187a0 3b 0a 20 20 20 20 20 20 75 38 20 2a 61 44 61 74  ;.      u8 *aDat
187b0 61 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 44 61  a;.      int nDa
187c0 74 61 3b 0a 20 20 20 20 20 20 69 6e 74 20 66 6c  ta;.      int fl
187d0 61 67 73 3b 0a 0a 20 20 20 20 20 20 72 63 20 3d  ags;..      rc =
187e0 20 6c 73 6d 46 73 44 62 50 61 67 65 47 65 74 28   lsmFsDbPageGet(
187f0 70 46 53 2c 20 70 53 65 67 2c 20 69 50 67 2c 20  pFS, pSeg, iPg, 
18800 26 70 50 67 29 3b 0a 20 20 20 20 20 20 69 66 28  &pPg);.      if(
18810 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 62 72   rc!=LSM_OK ) br
18820 65 61 6b 3b 0a 0a 20 20 20 20 20 20 61 44 61 74  eak;..      aDat
18830 61 20 3d 20 66 73 50 61 67 65 44 61 74 61 28 70  a = fsPageData(p
18840 50 67 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20 20  Pg, &nData);.   
18850 20 20 20 66 6c 61 67 73 20 3d 20 70 61 67 65 47     flags = pageG
18860 65 74 46 6c 61 67 73 28 61 44 61 74 61 2c 20 6e  etFlags(aData, n
18870 44 61 74 61 29 3b 0a 20 20 20 20 20 20 69 66 28  Data);.      if(
18880 20 66 6c 61 67 73 26 53 45 47 4d 45 4e 54 5f 42   flags&SEGMENT_B
18890 54 52 45 45 5f 46 4c 41 47 20 29 7b 0a 20 20 20  TREE_FLAG ){.   
188a0 20 20 20 20 20 50 61 67 65 20 2a 2a 61 70 4e 65       Page **apNe
188b0 77 20 3d 20 28 50 61 67 65 20 2a 2a 29 6c 73 6d  w = (Page **)lsm
188c0 52 65 61 6c 6c 6f 63 28 0a 20 20 20 20 20 20 20  Realloc(.       
188d0 20 20 20 20 20 70 45 6e 76 2c 20 61 70 48 69 65       pEnv, apHie
188e0 72 2c 20 73 69 7a 65 6f 66 28 50 61 67 65 20 2a  r, sizeof(Page *
188f0 29 2a 28 6e 48 69 65 72 2b 31 29 0a 20 20 20 20  )*(nHier+1).    
18900 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 69      );.        i
18910 66 28 20 61 70 4e 65 77 3d 3d 30 20 29 7b 0a 20  f( apNew==0 ){. 
18920 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 4c 53           rc = LS
18930 4d 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20  M_NOMEM_BKPT;.  
18940 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
18950 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
18960 20 61 70 48 69 65 72 20 3d 20 61 70 4e 65 77 3b   apHier = apNew;
18970 0a 20 20 20 20 20 20 20 20 6d 65 6d 6d 6f 76 65  .        memmove
18980 28 26 61 70 48 69 65 72 5b 31 5d 2c 20 26 61 70  (&apHier[1], &ap
18990 48 69 65 72 5b 30 5d 2c 20 73 69 7a 65 6f 66 28  Hier[0], sizeof(
189a0 50 61 67 65 20 2a 29 20 2a 20 6e 48 69 65 72 29  Page *) * nHier)
189b0 3b 0a 20 20 20 20 20 20 20 20 6e 48 69 65 72 2b  ;.        nHier+
189c0 2b 3b 0a 0a 20 20 20 20 20 20 20 20 61 70 48 69  +;..        apHi
189d0 65 72 5b 30 5d 20 3d 20 70 50 67 3b 0a 20 20 20  er[0] = pPg;.   
189e0 20 20 20 20 20 69 50 67 20 3d 20 70 61 67 65 47       iPg = pageG
189f0 65 74 50 74 72 28 61 44 61 74 61 2c 20 6e 44 61  etPtr(aData, nDa
18a00 74 61 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  ta);.      }else
18a10 7b 0a 20 20 20 20 20 20 20 20 6c 73 6d 46 73 50  {.        lsmFsP
18a20 61 67 65 52 65 6c 65 61 73 65 28 70 50 67 29 3b  ageRelease(pPg);
18a30 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
18a40 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 77 68 69        }.    }whi
18a50 6c 65 28 20 31 20 29 3b 0a 0a 20 20 20 20 69 66  le( 1 );..    if
18a60 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a  ( rc==LSM_OK ){.
18a70 20 20 20 20 20 20 75 38 20 2a 61 44 61 74 61 3b        u8 *aData;
18a80 0a 20 20 20 20 20 20 69 6e 74 20 6e 44 61 74 61  .      int nData
18a90 3b 0a 20 20 20 20 20 20 61 44 61 74 61 20 3d 20  ;.      aData = 
18aa0 66 73 50 61 67 65 44 61 74 61 28 61 70 48 69 65  fsPageData(apHie
18ab0 72 5b 30 5d 2c 20 26 6e 44 61 74 61 29 3b 0a 20  r[0], &nData);. 
18ac0 20 20 20 20 20 70 4d 57 2d 3e 61 53 61 76 65 5b       pMW->aSave[
18ad0 30 5d 2e 69 50 67 6e 6f 20 3d 20 70 61 67 65 47  0].iPgno = pageG
18ae0 65 74 50 74 72 28 61 44 61 74 61 2c 20 6e 44 61  etPtr(aData, nDa
18af0 74 61 29 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 48  ta);.      p->nH
18b00 69 65 72 20 3d 20 6e 48 69 65 72 3b 0a 20 20 20  ier = nHier;.   
18b10 20 20 20 70 2d 3e 61 70 48 69 65 72 20 3d 20 61     p->apHier = a
18b20 70 48 69 65 72 3b 0a 20 20 20 20 20 20 72 63 20  pHier;.      rc 
18b30 3d 20 6d 65 72 67 65 57 6f 72 6b 65 72 4d 6f 76  = mergeWorkerMov
18b40 65 48 69 65 72 61 72 63 68 79 28 70 4d 57 2c 20  eHierarchy(pMW, 
18b50 30 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  0);.    }else{. 
18b60 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20       int i;.    
18b70 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 48 69    for(i=0; i<nHi
18b80 65 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  er; i++){.      
18b90 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61    lsmFsPageRelea
18ba0 73 65 28 61 70 48 69 65 72 5b 69 5d 29 3b 0a 20  se(apHier[i]);. 
18bb0 20 20 20 20 20 7d 0a 20 20 20 20 20 20 6c 73 6d       }.      lsm
18bc0 46 72 65 65 28 70 45 6e 76 2c 20 61 70 48 69 65  Free(pEnv, apHie
18bd0 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  r);.    }.  }.. 
18be0 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
18bf0 2a 0a 2a 2a 20 42 2d 74 72 65 65 20 70 61 67 65  *.** B-tree page
18c00 73 20 75 73 65 20 61 6c 6d 6f 73 74 20 74 68 65  s use almost the
18c10 20 73 61 6d 65 20 66 6f 72 6d 61 74 20 61 73 20   same format as 
18c20 72 65 67 75 6c 61 72 20 70 61 67 65 73 2e 20 54  regular pages. T
18c30 68 65 20 0a 2a 2a 20 64 69 66 66 65 72 65 6e 63  he .** differenc
18c40 65 73 20 61 72 65 3a 0a 2a 2a 0a 2a 2a 20 20 20  es are:.**.**   
18c50 31 2e 20 54 68 65 20 72 65 63 6f 72 64 20 66 6f  1. The record fo
18c60 72 6d 61 74 20 69 73 20 28 75 73 75 61 6c 6c 79  rmat is (usually
18c70 2c 20 73 65 65 20 62 65 6c 6f 77 29 20 61 73 20  , see below) as 
18c80 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20  follows:.**.**  
18c90 20 20 20 20 20 20 20 2b 20 54 79 70 65 20 62 79         + Type by
18ca0 74 65 20 28 61 6c 77 61 79 73 20 53 4f 52 54 45  te (always SORTE
18cb0 44 5f 53 45 50 41 52 41 54 4f 52 20 6f 72 20 53  D_SEPARATOR or S
18cc0 4f 52 54 45 44 5f 53 59 53 54 45 4d 5f 53 45 50  ORTED_SYSTEM_SEP
18cd0 41 52 41 54 4f 52 29 2c 0a 2a 2a 20 20 20 20 20  ARATOR),.**     
18ce0 20 20 20 20 2b 20 41 62 73 6f 6c 75 74 65 20 70      + Absolute p
18cf0 6f 69 6e 74 65 72 20 76 61 6c 75 65 20 28 76 61  ointer value (va
18d00 72 69 6e 74 29 2c 0a 2a 2a 20 20 20 20 20 20 20  rint),.**       
18d10 20 20 2b 20 4e 75 6d 62 65 72 20 6f 66 20 62 79    + Number of by
18d20 74 65 73 20 69 6e 20 6b 65 79 20 28 76 61 72 69  tes in key (vari
18d30 6e 74 29 2c 0a 2a 2a 20 20 20 20 20 20 20 20 20  nt),.**         
18d40 2b 20 42 6c 6f 62 20 63 6f 6e 74 61 69 6e 69 6e  + Blob containin
18d50 67 20 6b 65 79 20 64 61 74 61 2e 0a 2a 2a 0a 2a  g key data..**.*
18d60 2a 20 20 20 32 2e 20 41 6c 6c 20 70 6f 69 6e 74  *   2. All point
18d70 65 72 20 76 61 6c 75 65 73 20 61 72 65 20 73 74  er values are st
18d80 6f 72 65 64 20 61 73 20 61 62 73 6f 6c 75 74 65  ored as absolute
18d90 20 76 61 6c 75 65 73 20 28 6e 6f 74 20 6f 66 66   values (not off
18da0 73 65 74 73 20 0a 2a 2a 20 20 20 20 20 20 72 65  sets .**      re
18db0 6c 61 74 69 76 65 20 74 6f 20 74 68 65 20 66 6f  lative to the fo
18dc0 6f 74 65 72 20 70 6f 69 6e 74 65 72 20 76 61 6c  oter pointer val
18dd0 75 65 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 33 2e 20  ue)..**.**   3. 
18de0 45 61 63 68 20 70 6f 69 6e 74 65 72 20 74 68 61  Each pointer tha
18df0 74 20 69 73 20 70 61 72 74 20 6f 66 20 61 20 72  t is part of a r
18e00 65 63 6f 72 64 20 70 6f 69 6e 74 73 20 74 6f 20  ecord points to 
18e10 61 20 70 61 67 65 20 74 68 61 74 20 0a 2a 2a 20  a page that .** 
18e20 20 20 20 20 20 63 6f 6e 74 61 69 6e 73 20 6b 65       contains ke
18e30 79 73 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20  ys smaller than 
18e40 74 68 65 20 72 65 63 6f 72 64 73 20 6b 65 79 20  the records key 
18e50 28 6e 6f 74 65 3a 20 6e 6f 74 20 22 65 71 75 61  (note: not "equa
18e60 6c 20 74 6f 20 6f 72 0a 2a 2a 20 20 20 20 20 20  l to or.**      
18e70 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 2d 20 73  smaller than - s
18e80 6d 61 6c 6c 65 72 20 74 68 61 6e 22 29 2e 0a 2a  maller than")..*
18e90 2a 0a 2a 2a 20 20 20 34 2e 20 54 68 65 20 70 6f  *.**   4. The po
18ea0 69 6e 74 65 72 20 69 6e 20 74 68 65 20 70 61 67  inter in the pag
18eb0 65 20 66 6f 6f 74 65 72 20 6f 66 20 61 20 62 2d  e footer of a b-
18ec0 74 72 65 65 20 70 61 67 65 20 70 6f 69 6e 74 73  tree page points
18ed0 20 74 6f 20 61 20 70 61 67 65 0a 2a 2a 20 20 20   to a page.**   
18ee0 20 20 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73     that contains
18ef0 20 6b 65 79 73 20 65 71 75 61 6c 20 74 6f 20 6f   keys equal to o
18f00 72 20 6c 61 72 67 65 72 20 74 68 61 6e 20 74 68  r larger than th
18f10 65 20 6c 61 72 67 65 73 74 20 6b 65 79 20 6f 6e  e largest key on
18f20 20 74 68 65 0a 2a 2a 20 20 20 20 20 20 62 2d 74   the.**      b-t
18f30 72 65 65 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20  ree page..**.** 
18f40 54 68 65 20 72 65 61 73 6f 6e 20 66 6f 72 20 68  The reason for h
18f50 61 76 69 6e 67 20 74 68 65 20 70 61 67 65 20 66  aving the page f
18f60 6f 6f 74 65 72 20 70 6f 69 6e 74 65 72 20 70 6f  ooter pointer po
18f70 69 6e 74 20 74 6f 20 74 68 65 20 72 69 67 68 74  int to the right
18f80 2d 63 68 69 6c 64 0a 2a 2a 20 28 69 6e 73 74 65  -child.** (inste
18f90 61 64 20 6f 66 20 74 68 65 20 6c 65 66 74 29 20  ad of the left) 
18fa0 69 73 20 74 68 61 74 20 64 6f 69 6e 67 20 74 68  is that doing th
18fb0 69 6e 67 73 20 74 68 69 73 20 77 61 79 20 6d 61  ings this way ma
18fc0 6b 65 73 20 74 68 65 20 0a 2a 2a 20 6d 65 72 67  kes the .** merg
18fd0 65 57 6f 72 6b 65 72 4d 6f 76 65 48 69 65 72 61  eWorkerMoveHiera
18fe0 72 63 68 79 28 29 20 6f 70 65 72 61 74 69 6f 6e  rchy() operation
18ff0 20 6c 65 73 73 20 63 6f 6d 70 6c 69 63 61 74 65   less complicate
19000 64 20 28 73 69 6e 63 65 20 74 68 65 20 70 6f 69  d (since the poi
19010 6e 74 65 72 73 20 0a 2a 2a 20 74 68 61 74 20 6e  nters .** that n
19020 65 65 64 20 74 6f 20 62 65 20 75 70 64 61 74 65  eed to be update
19030 64 20 61 72 65 20 61 6c 6c 20 73 74 6f 72 65 64  d are all stored
19040 20 61 73 20 66 69 78 65 64 2d 73 69 7a 65 20 69   as fixed-size i
19050 6e 74 65 67 65 72 73 20 77 69 74 68 69 6e 20 74  ntegers within t
19060 68 65 20 0a 2a 2a 20 70 61 67 65 20 66 6f 6f 74  he .** page foot
19070 65 72 2c 20 6e 6f 74 20 76 61 72 69 6e 74 73 20  er, not varints 
19080 69 6e 20 70 61 67 65 20 72 65 63 6f 72 64 73 29  in page records)
19090 2e 0a 2a 2a 0a 2a 2a 20 52 65 63 6f 72 64 73 20  ..**.** Records 
190a0 6d 61 79 20 6e 6f 74 20 73 70 61 6e 20 62 2d 74  may not span b-t
190b0 72 65 65 20 70 61 67 65 73 2e 20 49 66 20 74 68  ree pages. If th
190c0 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
190d0 61 6c 6c 65 64 20 74 6f 20 61 64 64 20 61 0a 2a  alled to add a.*
190e0 2a 20 72 65 63 6f 72 64 20 6c 61 72 67 65 72 20  * record larger 
190f0 74 68 61 6e 20 28 70 61 67 65 2d 73 69 7a 65 20  than (page-size 
19100 2f 20 34 29 20 62 79 74 65 73 2c 20 74 68 65 6e  / 4) bytes, then
19110 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   a pointer to th
19120 65 20 69 6e 64 65 78 65 64 0a 2a 2a 20 61 72 72  e indexed.** arr
19130 61 79 20 70 61 67 65 20 74 68 61 74 20 63 6f 6e  ay page that con
19140 74 61 69 6e 73 20 74 68 65 20 6d 61 69 6e 20 72  tains the main r
19150 65 63 6f 72 64 20 69 73 20 61 64 64 65 64 20 74  ecord is added t
19160 6f 20 74 68 65 20 62 2d 74 72 65 65 20 69 6e 73  o the b-tree ins
19170 74 65 61 64 2e 0a 2a 2a 20 49 6e 20 74 68 69 73  tead..** In this
19180 20 63 61 73 65 20 74 68 65 20 72 65 63 6f 72 64   case the record
19190 20 66 6f 72 6d 61 74 20 69 73 3a 0a 2a 2a 0a 2a   format is:.**.*
191a0 2a 20 20 20 20 20 20 20 20 20 2b 20 30 78 30 30  *         + 0x00
191b0 20 62 79 74 65 20 28 31 20 62 79 74 65 29 20 0a   byte (1 byte) .
191c0 2a 2a 20 20 20 20 20 20 20 20 20 2b 20 41 62 73  **         + Abs
191d0 6f 6c 75 74 65 20 70 6f 69 6e 74 65 72 20 76 61  olute pointer va
191e0 6c 75 65 20 28 76 61 72 69 6e 74 29 2c 0a 2a 2a  lue (varint),.**
191f0 20 20 20 20 20 20 20 20 20 2b 20 41 62 73 6f 6c           + Absol
19200 75 74 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  ute page number 
19210 6f 66 20 70 61 67 65 20 63 6f 6e 74 61 69 6e 69  of page containi
19220 6e 67 20 6b 65 79 20 28 76 61 72 69 6e 74 29 2e  ng key (varint).
19230 0a 2a 2a 0a 2a 2a 20 53 65 65 20 66 75 6e 63 74  .**.** See funct
19240 69 6f 6e 20 73 65 65 6b 49 6e 42 74 72 65 65 28  ion seekInBtree(
19250 29 20 66 6f 72 20 74 68 65 20 63 6f 64 65 20 74  ) for the code t
19260 68 61 74 20 74 72 61 76 65 72 73 65 73 20 62 2d  hat traverses b-
19270 74 72 65 65 20 70 61 67 65 73 2e 0a 2a 2f 0a 0a  tree pages..*/..
19280 73 74 61 74 69 63 20 69 6e 74 20 6d 65 72 67 65  static int merge
19290 57 6f 72 6b 65 72 42 74 72 65 65 57 72 69 74 65  WorkerBtreeWrite
192a0 28 0a 20 20 4d 65 72 67 65 57 6f 72 6b 65 72 20  (.  MergeWorker 
192b0 2a 70 4d 57 2c 0a 20 20 75 38 20 65 54 79 70 65  *pMW,.  u8 eType
192c0 2c 0a 20 20 50 67 6e 6f 20 69 50 74 72 2c 0a 20  ,.  Pgno iPtr,. 
192d0 20 50 67 6e 6f 20 69 4b 65 79 50 67 2c 0a 20 20   Pgno iKeyPg,.  
192e0 76 6f 69 64 20 2a 70 4b 65 79 2c 0a 20 20 69 6e  void *pKey,.  in
192f0 74 20 6e 4b 65 79 0a 29 7b 0a 20 20 48 69 65 72  t nKey.){.  Hier
19300 61 72 63 68 79 20 2a 70 20 3d 20 26 70 4d 57 2d  archy *p = &pMW-
19310 3e 68 69 65 72 3b 0a 20 20 6c 73 6d 5f 64 62 20  >hier;.  lsm_db 
19320 2a 70 44 62 20 3d 20 70 4d 57 2d 3e 70 44 62 3b  *pDb = pMW->pDb;
19330 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
19340 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20  base handle */. 
19350 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
19360 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
19370 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20   /* Return Code 
19380 2a 2f 0a 20 20 69 6e 74 20 69 4c 65 76 65 6c 3b  */.  int iLevel;
19390 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
193a0 20 20 20 20 20 2f 2a 20 4c 65 76 65 6c 20 6f 66       /* Level of
193b0 20 62 2d 74 72 65 65 20 68 69 65 72 61 63 68 79   b-tree hierachy
193c0 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a   to write to */.
193d0 20 20 69 6e 74 20 6e 44 61 74 61 3b 20 20 20 20    int nData;    
193e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
193f0 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 44 61    /* Size of aDa
19400 74 61 5b 5d 20 69 6e 20 62 79 74 65 73 20 2a 2f  ta[] in bytes */
19410 0a 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20 20  .  u8 *aData;   
19420 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19430 20 20 20 2f 2a 20 50 61 67 65 20 64 61 74 61 20     /* Page data 
19440 66 6f 72 20 6c 65 76 65 6c 20 69 4c 65 76 65 6c  for level iLevel
19450 20 2a 2f 0a 20 20 69 6e 74 20 69 4f 66 66 3b 20   */.  int iOff; 
19460 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19470 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20        /* Offset 
19480 6f 6e 20 62 2d 74 72 65 65 20 70 61 67 65 20 74  on b-tree page t
19490 6f 20 77 72 69 74 65 20 72 65 63 6f 72 64 20 74  o write record t
194a0 6f 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 63 3b  o */.  int nRec;
194b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
194c0 20 20 20 20 20 20 20 2f 2a 20 49 6e 69 74 69 61         /* Initia
194d0 6c 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 63 6f  l number of reco
194e0 72 64 73 20 6f 6e 20 62 2d 74 72 65 65 20 70 61  rds on b-tree pa
194f0 67 65 20 2a 2f 0a 0a 20 20 2f 2a 20 69 4b 65 79  ge */..  /* iKey
19500 50 67 20 73 68 6f 75 6c 64 20 62 65 20 7a 65 72  Pg should be zer
19510 6f 20 66 6f 72 20 61 6e 20 6f 72 64 69 6e 61 72  o for an ordinar
19520 79 20 62 2d 74 72 65 65 20 6b 65 79 2c 20 6f 72  y b-tree key, or
19530 20 6e 6f 6e 2d 7a 65 72 6f 20 66 6f 72 20 61 6e   non-zero for an
19540 0a 20 20 2a 2a 20 69 6e 64 69 72 65 63 74 20 6b  .  ** indirect k
19550 65 79 2e 20 54 68 65 20 66 6c 61 67 73 20 62 79  ey. The flags by
19560 74 65 20 66 6f 72 20 61 6e 20 69 6e 64 69 72 65  te for an indire
19570 63 74 20 6b 65 79 20 69 73 20 30 78 30 30 2e 20  ct key is 0x00. 
19580 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 28 65   */.  assert( (e
19590 54 79 70 65 3d 3d 30 29 3d 3d 28 69 4b 65 79 50  Type==0)==(iKeyP
195a0 67 21 3d 30 29 20 29 3b 0a 0a 20 20 2f 2a 20 54  g!=0) );..  /* T
195b0 68 65 20 4d 65 72 67 65 57 6f 72 6b 65 72 2e 61  he MergeWorker.a
195c0 70 48 69 65 72 5b 5d 20 61 72 72 61 79 20 63 6f  pHier[] array co
195d0 6e 74 61 69 6e 73 20 74 68 65 20 72 69 67 68 74  ntains the right
195e0 2d 6d 6f 73 74 20 6c 65 61 66 20 6f 66 20 74 68  -most leaf of th
195f0 65 20 62 2d 74 72 65 65 0a 20 20 2a 2a 20 68 69  e b-tree.  ** hi
19600 65 72 61 72 63 68 79 2c 20 74 68 65 20 72 6f 6f  erarchy, the roo
19610 74 20 6e 6f 64 65 2c 20 61 6e 64 20 61 6c 6c 20  t node, and all 
19620 6e 6f 64 65 73 20 74 68 61 74 20 6c 69 65 20 6f  nodes that lie o
19630 6e 20 74 68 65 20 70 61 74 68 20 62 65 74 77 65  n the path betwe
19640 65 6e 2e 0a 20 20 2a 2a 20 61 70 48 69 65 72 5b  en..  ** apHier[
19650 30 5d 20 69 73 20 74 68 65 20 72 69 67 68 74 2d  0] is the right-
19660 6d 6f 73 74 20 6c 65 61 66 20 61 6e 64 20 61 70  most leaf and ap
19670 48 69 65 72 5b 70 4d 57 2d 3e 6e 48 69 65 72 2d  Hier[pMW->nHier-
19680 31 5d 20 69 73 20 74 68 65 20 63 75 72 72 65 6e  1] is the curren
19690 74 0a 20 20 2a 2a 20 72 6f 6f 74 20 70 61 67 65  t.  ** root page
196a0 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 69 73  ..  **.  ** This
196b0 20 6c 6f 6f 70 20 73 65 61 72 63 68 65 73 20 66   loop searches f
196c0 6f 72 20 61 20 6e 6f 64 65 20 77 69 74 68 20 65  or a node with e
196d0 6e 6f 75 67 68 20 73 70 61 63 65 20 74 6f 20 73  nough space to s
196e0 74 6f 72 65 20 74 68 65 20 6b 65 79 20 6f 6e 2c  tore the key on,
196f0 0a 20 20 2a 2a 20 73 74 61 72 74 69 6e 67 20 77  .  ** starting w
19700 69 74 68 20 74 68 65 20 6c 65 61 66 20 61 6e 64  ith the leaf and
19710 20 69 74 65 72 61 74 69 6e 67 20 75 70 20 74 6f   iterating up to
19720 77 61 72 64 73 20 74 68 65 20 72 6f 6f 74 2e 20  wards the root. 
19730 57 68 65 6e 20 74 68 65 20 6c 6f 6f 70 0a 20 20  When the loop.  
19740 2a 2a 20 65 78 69 74 73 2c 20 74 68 65 20 6b 65  ** exits, the ke
19750 79 20 6d 61 79 20 62 65 20 77 72 69 74 74 65 6e  y may be written
19760 20 74 6f 20 61 70 48 69 65 72 5b 69 4c 65 76 65   to apHier[iLeve
19770 6c 5d 2e 20 20 2a 2f 0a 20 20 66 6f 72 28 69 4c  l].  */.  for(iL
19780 65 76 65 6c 3d 30 3b 20 69 4c 65 76 65 6c 3c 3d  evel=0; iLevel<=
19790 70 2d 3e 6e 48 69 65 72 3b 20 69 4c 65 76 65 6c  p->nHier; iLevel
197a0 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79  ++){.    int nBy
197b0 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  te;             
197c0 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
197d0 20 6f 66 20 66 72 65 65 20 62 79 74 65 73 20 72   of free bytes r
197e0 65 71 75 69 72 65 64 20 2a 2f 0a 0a 20 20 20 20  equired */..    
197f0 69 66 28 20 69 4c 65 76 65 6c 3d 3d 70 2d 3e 6e  if( iLevel==p->n
19800 48 69 65 72 20 29 7b 0a 20 20 20 20 20 20 2f 2a  Hier ){.      /*
19810 20 45 78 74 65 6e 64 20 74 68 65 20 61 72 72 61   Extend the arra
19820 79 20 61 6e 64 20 61 6c 6c 6f 63 61 74 65 20 61  y and allocate a
19830 20 6e 65 77 20 72 6f 6f 74 20 70 61 67 65 2e 20   new root page. 
19840 2a 2f 0a 20 20 20 20 20 20 50 61 67 65 20 2a 2a  */.      Page **
19850 61 4e 65 77 3b 0a 20 20 20 20 20 20 61 4e 65 77  aNew;.      aNew
19860 20 3d 20 28 50 61 67 65 20 2a 2a 29 6c 73 6d 52   = (Page **)lsmR
19870 65 61 6c 6c 6f 63 28 0a 20 20 20 20 20 20 20 20  ealloc(.        
19880 20 20 70 4d 57 2d 3e 70 44 62 2d 3e 70 45 6e 76    pMW->pDb->pEnv
19890 2c 20 70 2d 3e 61 70 48 69 65 72 2c 20 73 69 7a  , p->apHier, siz
198a0 65 6f 66 28 50 61 67 65 20 2a 29 2a 28 70 2d 3e  eof(Page *)*(p->
198b0 6e 48 69 65 72 2b 31 29 0a 20 20 20 20 20 20 29  nHier+1).      )
198c0 3b 0a 20 20 20 20 20 20 69 66 28 20 21 61 4e 65  ;.      if( !aNe
198d0 77 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74  w ){.        ret
198e0 75 72 6e 20 4c 53 4d 5f 4e 4f 4d 45 4d 5f 42 4b  urn LSM_NOMEM_BK
198f0 50 54 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  PT;.      }.    
19900 20 20 70 2d 3e 61 70 48 69 65 72 20 3d 20 61 4e    p->apHier = aN
19910 65 77 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ew;.    }else{. 
19920 20 20 20 20 20 50 61 67 65 20 2a 70 4f 6c 64 3b       Page *pOld;
19930 0a 20 20 20 20 20 20 69 6e 74 20 6e 46 72 65 65  .      int nFree
19940 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 74  ;..      /* If t
19950 68 65 20 6b 65 79 20 77 69 6c 6c 20 66 69 74 20  he key will fit 
19960 6f 6e 20 74 68 69 73 20 70 61 67 65 2c 20 62 72  on this page, br
19970 65 61 6b 20 6f 75 74 20 6f 66 20 74 68 65 20 6c  eak out of the l
19980 6f 6f 70 20 68 65 72 65 2e 0a 20 20 20 20 20 20  oop here..      
19990 2a 2a 20 54 68 65 20 6e 65 77 20 65 6e 74 72 79  ** The new entry
199a0 20 77 69 6c 6c 20 62 65 20 77 72 69 74 74 65 6e   will be written
199b0 20 74 6f 20 70 61 67 65 20 61 70 48 69 65 72 5b   to page apHier[
199c0 69 4c 65 76 65 6c 5d 2e 20 2a 2f 0a 20 20 20 20  iLevel]. */.    
199d0 20 20 70 4f 6c 64 20 3d 20 70 2d 3e 61 70 48 69    pOld = p->apHi
199e0 65 72 5b 69 4c 65 76 65 6c 5d 3b 0a 20 20 20 20  er[iLevel];.    
199f0 20 20 61 73 73 65 72 74 28 20 6c 73 6d 46 73 50    assert( lsmFsP
19a00 61 67 65 57 72 69 74 61 62 6c 65 28 70 4f 6c 64  ageWritable(pOld
19a10 29 20 29 3b 0a 20 20 20 20 20 20 61 44 61 74 61  ) );.      aData
19a20 20 3d 20 66 73 50 61 67 65 44 61 74 61 28 70 4f   = fsPageData(pO
19a30 6c 64 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20 20  ld, &nData);.   
19a40 20 20 20 69 66 28 20 65 54 79 70 65 3d 3d 30 20     if( eType==0 
19a50 29 7b 0a 20 20 20 20 20 20 20 20 6e 42 79 74 65  ){.        nByte
19a60 20 3d 20 32 20 2b 20 31 20 2b 20 6c 73 6d 56 61   = 2 + 1 + lsmVa
19a70 72 69 6e 74 4c 65 6e 33 32 28 69 50 74 72 29 20  rintLen32(iPtr) 
19a80 2b 20 6c 73 6d 56 61 72 69 6e 74 4c 65 6e 33 32  + lsmVarintLen32
19a90 28 69 4b 65 79 50 67 29 3b 0a 20 20 20 20 20 20  (iKeyPg);.      
19aa0 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 6e  }else{.        n
19ab0 42 79 74 65 20 3d 20 32 20 2b 20 31 20 2b 20 6c  Byte = 2 + 1 + l
19ac0 73 6d 56 61 72 69 6e 74 4c 65 6e 33 32 28 69 50  smVarintLen32(iP
19ad0 74 72 29 20 2b 20 6c 73 6d 56 61 72 69 6e 74 4c  tr) + lsmVarintL
19ae0 65 6e 33 32 28 6e 4b 65 79 29 20 2b 20 6e 4b 65  en32(nKey) + nKe
19af0 79 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  y;.      }.     
19b00 20 6e 52 65 63 20 3d 20 70 61 67 65 47 65 74 4e   nRec = pageGetN
19b10 52 65 63 28 61 44 61 74 61 2c 20 6e 44 61 74 61  Rec(aData, nData
19b20 29 3b 0a 20 20 20 20 20 20 6e 46 72 65 65 20 3d  );.      nFree =
19b30 20 53 45 47 4d 45 4e 54 5f 45 4f 46 28 6e 44 61   SEGMENT_EOF(nDa
19b40 74 61 2c 20 6e 52 65 63 29 20 2d 20 6d 65 72 67  ta, nRec) - merg
19b50 65 57 6f 72 6b 65 72 50 61 67 65 4f 66 66 73 65  eWorkerPageOffse
19b60 74 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b  t(aData, nData);
19b70 0a 20 20 20 20 20 20 69 66 28 20 6e 42 79 74 65  .      if( nByte
19b80 3c 3d 6e 46 72 65 65 20 29 20 62 72 65 61 6b 3b  <=nFree ) break;
19b90 0a 0a 20 20 20 20 20 20 2f 2a 20 4f 74 68 65 72  ..      /* Other
19ba0 77 69 73 65 2c 20 74 68 69 73 20 70 61 67 65 20  wise, this page 
19bb0 69 73 20 66 75 6c 6c 2e 20 53 65 74 20 74 68 65  is full. Set the
19bc0 20 72 69 67 68 74 2d 68 61 6e 64 2d 63 68 69 6c   right-hand-chil
19bd0 64 20 70 6f 69 6e 74 65 72 0a 20 20 20 20 20 20  d pointer.      
19be0 2a 2a 20 74 6f 20 69 50 74 72 20 61 6e 64 20 72  ** to iPtr and r
19bf0 65 6c 65 61 73 65 20 69 74 2e 20 20 2a 2f 0a 20  elease it.  */. 
19c00 20 20 20 20 20 6c 73 6d 50 75 74 55 36 34 28 26       lsmPutU64(&
19c10 61 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f 50 4f  aData[SEGMENT_PO
19c20 49 4e 54 45 52 5f 4f 46 46 53 45 54 28 6e 44 61  INTER_OFFSET(nDa
19c30 74 61 29 5d 2c 20 69 50 74 72 29 3b 0a 20 20 20  ta)], iPtr);.   
19c40 20 20 20 61 73 73 65 72 74 28 20 6c 73 6d 46 73     assert( lsmFs
19c50 50 61 67 65 4e 75 6d 62 65 72 28 70 4f 6c 64 29  PageNumber(pOld)
19c60 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 72 63 20  ==0 );.      rc 
19c70 3d 20 6c 73 6d 46 73 50 61 67 65 50 65 72 73 69  = lsmFsPagePersi
19c80 73 74 28 70 4f 6c 64 29 3b 0a 20 20 20 20 20 20  st(pOld);.      
19c90 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
19ca0 7b 0a 20 20 20 20 20 20 20 20 69 50 74 72 20 3d  {.        iPtr =
19cb0 20 6c 73 6d 46 73 50 61 67 65 4e 75 6d 62 65 72   lsmFsPageNumber
19cc0 28 70 4f 6c 64 29 3b 0a 20 20 20 20 20 20 20 20  (pOld);.        
19cd0 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61 73 65  lsmFsPageRelease
19ce0 28 70 4f 6c 64 29 3b 0a 20 20 20 20 20 20 7d 0a  (pOld);.      }.
19cf0 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 41 6c      }..    /* Al
19d00 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67  locate a new pag
19d10 65 20 66 6f 72 20 61 70 48 69 65 72 5b 69 4c 65  e for apHier[iLe
19d20 76 65 6c 5d 2e 20 2a 2f 0a 20 20 20 20 70 2d 3e  vel]. */.    p->
19d30 61 70 48 69 65 72 5b 69 4c 65 76 65 6c 5d 20 3d  apHier[iLevel] =
19d40 20 30 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d   0;.    if( rc==
19d50 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  LSM_OK ){.      
19d60 72 63 20 3d 20 6c 73 6d 46 73 53 6f 72 74 65 64  rc = lsmFsSorted
19d70 41 70 70 65 6e 64 28 0a 20 20 20 20 20 20 20 20  Append(.        
19d80 20 20 70 44 62 2d 3e 70 46 53 2c 20 70 44 62 2d    pDb->pFS, pDb-
19d90 3e 70 57 6f 72 6b 65 72 2c 20 70 4d 57 2d 3e 70  >pWorker, pMW->p
19da0 4c 65 76 65 6c 2c 20 31 2c 20 26 70 2d 3e 61 70  Level, 1, &p->ap
19db0 48 69 65 72 5b 69 4c 65 76 65 6c 5d 0a 20 20 20  Hier[iLevel].   
19dc0 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20     );.    }.    
19dd0 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29  if( rc!=LSM_OK )
19de0 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20   return rc;..   
19df0 20 61 44 61 74 61 20 3d 20 66 73 50 61 67 65 44   aData = fsPageD
19e00 61 74 61 28 70 2d 3e 61 70 48 69 65 72 5b 69 4c  ata(p->apHier[iL
19e10 65 76 65 6c 5d 2c 20 26 6e 44 61 74 61 29 3b 0a  evel], &nData);.
19e20 20 20 20 20 6d 65 6d 73 65 74 28 61 44 61 74 61      memset(aData
19e30 2c 20 30 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20  , 0, nData);.   
19e40 20 6c 73 6d 50 75 74 55 31 36 28 26 61 44 61 74   lsmPutU16(&aDat
19e50 61 5b 53 45 47 4d 45 4e 54 5f 46 4c 41 47 53 5f  a[SEGMENT_FLAGS_
19e60 4f 46 46 53 45 54 28 6e 44 61 74 61 29 5d 2c 20  OFFSET(nData)], 
19e70 53 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c  SEGMENT_BTREE_FL
19e80 41 47 29 3b 0a 20 20 20 20 6c 73 6d 50 75 74 55  AG);.    lsmPutU
19e90 31 36 28 26 61 44 61 74 61 5b 53 45 47 4d 45 4e  16(&aData[SEGMEN
19ea0 54 5f 4e 52 45 43 4f 52 44 5f 4f 46 46 53 45 54  T_NRECORD_OFFSET
19eb0 28 6e 44 61 74 61 29 5d 2c 20 30 29 3b 0a 0a 20  (nData)], 0);.. 
19ec0 20 20 20 69 66 28 20 69 4c 65 76 65 6c 3d 3d 70     if( iLevel==p
19ed0 2d 3e 6e 48 69 65 72 20 29 7b 0a 20 20 20 20 20  ->nHier ){.     
19ee0 20 70 2d 3e 6e 48 69 65 72 2b 2b 3b 0a 20 20 20   p->nHier++;.   
19ef0 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
19f00 20 20 7d 0a 0a 20 20 2f 2a 20 57 72 69 74 65 20    }..  /* Write 
19f10 74 68 65 20 6b 65 79 20 69 6e 74 6f 20 70 61 67  the key into pag
19f20 65 20 61 70 48 69 65 72 5b 69 4c 65 76 65 6c 5d  e apHier[iLevel]
19f30 2e 20 2a 2f 0a 20 20 61 44 61 74 61 20 3d 20 66  . */.  aData = f
19f40 73 50 61 67 65 44 61 74 61 28 70 2d 3e 61 70 48  sPageData(p->apH
19f50 69 65 72 5b 69 4c 65 76 65 6c 5d 2c 20 26 6e 44  ier[iLevel], &nD
19f60 61 74 61 29 3b 0a 20 20 69 4f 66 66 20 3d 20 6d  ata);.  iOff = m
19f70 65 72 67 65 57 6f 72 6b 65 72 50 61 67 65 4f 66  ergeWorkerPageOf
19f80 66 73 65 74 28 61 44 61 74 61 2c 20 6e 44 61 74  fset(aData, nDat
19f90 61 29 3b 0a 20 20 6e 52 65 63 20 3d 20 70 61 67  a);.  nRec = pag
19fa0 65 47 65 74 4e 52 65 63 28 61 44 61 74 61 2c 20  eGetNRec(aData, 
19fb0 6e 44 61 74 61 29 3b 0a 20 20 6c 73 6d 50 75 74  nData);.  lsmPut
19fc0 55 31 36 28 26 61 44 61 74 61 5b 53 45 47 4d 45  U16(&aData[SEGME
19fd0 4e 54 5f 43 45 4c 4c 50 54 52 5f 4f 46 46 53 45  NT_CELLPTR_OFFSE
19fe0 54 28 6e 44 61 74 61 2c 20 6e 52 65 63 29 5d 2c  T(nData, nRec)],
19ff0 20 69 4f 66 66 29 3b 0a 20 20 6c 73 6d 50 75 74   iOff);.  lsmPut
1a000 55 31 36 28 26 61 44 61 74 61 5b 53 45 47 4d 45  U16(&aData[SEGME
1a010 4e 54 5f 4e 52 45 43 4f 52 44 5f 4f 46 46 53 45  NT_NRECORD_OFFSE
1a020 54 28 6e 44 61 74 61 29 5d 2c 20 6e 52 65 63 2b  T(nData)], nRec+
1a030 31 29 3b 0a 20 20 69 66 28 20 65 54 79 70 65 3d  1);.  if( eType=
1a040 3d 30 20 29 7b 0a 20 20 20 20 61 44 61 74 61 5b  =0 ){.    aData[
1a050 69 4f 66 66 2b 2b 5d 20 3d 20 30 78 30 30 3b 0a  iOff++] = 0x00;.
1a060 20 20 20 20 69 4f 66 66 20 2b 3d 20 6c 73 6d 56      iOff += lsmV
1a070 61 72 69 6e 74 50 75 74 33 32 28 26 61 44 61 74  arintPut32(&aDat
1a080 61 5b 69 4f 66 66 5d 2c 20 69 50 74 72 29 3b 0a  a[iOff], iPtr);.
1a090 20 20 20 20 69 4f 66 66 20 2b 3d 20 6c 73 6d 56      iOff += lsmV
1a0a0 61 72 69 6e 74 50 75 74 33 32 28 26 61 44 61 74  arintPut32(&aDat
1a0b0 61 5b 69 4f 66 66 5d 2c 20 69 4b 65 79 50 67 29  a[iOff], iKeyPg)
1a0c0 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61  ;.  }else{.    a
1a0d0 44 61 74 61 5b 69 4f 66 66 2b 2b 5d 20 3d 20 65  Data[iOff++] = e
1a0e0 54 79 70 65 3b 0a 20 20 20 20 69 4f 66 66 20 2b  Type;.    iOff +
1a0f0 3d 20 6c 73 6d 56 61 72 69 6e 74 50 75 74 33 32  = lsmVarintPut32
1a100 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c 20 69  (&aData[iOff], i
1a110 50 74 72 29 3b 0a 20 20 20 20 69 4f 66 66 20 2b  Ptr);.    iOff +
1a120 3d 20 6c 73 6d 56 61 72 69 6e 74 50 75 74 33 32  = lsmVarintPut32
1a130 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c 20 6e  (&aData[iOff], n
1a140 4b 65 79 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79  Key);.    memcpy
1a150 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c 20 70  (&aData[iOff], p
1a160 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 20 20 7d 0a  Key, nKey);.  }.
1a170 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
1a180 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 72 67  .static int merg
1a190 65 57 6f 72 6b 65 72 42 74 72 65 65 49 6e 64 69  eWorkerBtreeIndi
1a1a0 72 65 63 74 28 4d 65 72 67 65 57 6f 72 6b 65 72  rect(MergeWorker
1a1b0 20 2a 70 4d 57 29 7b 0a 20 20 69 6e 74 20 72 63   *pMW){.  int rc
1a1c0 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 69 66 28   = LSM_OK;.  if(
1a1d0 20 70 4d 57 2d 3e 69 49 6e 64 69 72 65 63 74 20   pMW->iIndirect 
1a1e0 29 7b 0a 20 20 20 20 50 67 6e 6f 20 69 4b 65 79  ){.    Pgno iKey
1a1f0 50 67 20 3d 20 70 4d 57 2d 3e 61 53 61 76 65 5b  Pg = pMW->aSave[
1a200 31 5d 2e 69 50 67 6e 6f 3b 0a 20 20 20 20 72 63  1].iPgno;.    rc
1a210 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65 72 42 74   = mergeWorkerBt
1a220 72 65 65 57 72 69 74 65 28 70 4d 57 2c 20 30 2c  reeWrite(pMW, 0,
1a230 20 70 4d 57 2d 3e 69 49 6e 64 69 72 65 63 74 2c   pMW->iIndirect,
1a240 20 69 4b 65 79 50 67 2c 20 30 2c 20 30 29 3b 0a   iKeyPg, 0, 0);.
1a250 20 20 20 20 70 4d 57 2d 3e 69 49 6e 64 69 72 65      pMW->iIndire
1a260 63 74 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65  ct = 0;.  }.  re
1a270 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
1a280 2a 20 41 70 70 65 6e 64 20 74 68 65 20 64 61 74  * Append the dat
1a290 61 62 61 73 65 20 6b 65 79 20 28 69 54 6f 70 69  abase key (iTopi
1a2a0 63 2f 70 4b 65 79 2f 6e 4b 65 79 29 20 74 6f 20  c/pKey/nKey) to 
1a2b0 74 68 65 20 62 2d 74 72 65 65 20 75 6e 64 65 72  the b-tree under
1a2c0 20 0a 2a 2a 20 63 6f 6e 73 74 72 75 63 74 69 6f   .** constructio
1a2d0 6e 2e 20 54 68 69 73 20 6b 65 79 20 68 61 73 20  n. This key has 
1a2e0 6e 6f 74 20 79 65 74 20 62 65 65 6e 20 77 72 69  not yet been wri
1a2f0 74 74 65 6e 20 74 6f 20 61 20 73 65 67 6d 65 6e  tten to a segmen
1a300 74 20 70 61 67 65 2e 0a 2a 2a 20 54 68 65 20 70  t page..** The p
1a310 6f 69 6e 74 65 72 20 74 68 61 74 20 77 69 6c 6c  ointer that will
1a320 20 61 63 63 6f 6d 70 61 6e 79 20 74 68 65 20 6e   accompany the n
1a330 65 77 20 6b 65 79 20 69 6e 20 74 68 65 20 62 2d  ew key in the b-
1a340 74 72 65 65 20 2d 20 74 68 61 74 0a 2a 2a 20 70  tree - that.** p
1a350 6f 69 6e 74 73 20 74 6f 20 74 68 65 20 63 6f 6d  oints to the com
1a360 70 6c 65 74 65 64 20 73 65 67 6d 65 6e 74 20 70  pleted segment p
1a370 61 67 65 20 74 68 61 74 20 63 6f 6e 74 61 69 6e  age that contain
1a380 73 20 6b 65 79 73 20 73 6d 61 6c 6c 65 72 20 74  s keys smaller t
1a390 68 61 6e 0a 2a 2a 20 28 70 4b 65 79 2f 6e 4b 65  han.** (pKey/nKe
1a3a0 79 29 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20  y) is currently 
1a3b0 73 74 6f 72 65 64 20 69 6e 20 70 4d 57 2d 3e 61  stored in pMW->a
1a3c0 53 61 76 65 5b 30 5d 2e 69 50 67 6e 6f 2e 0a 2a  Save[0].iPgno..*
1a3d0 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 72  /.static int mer
1a3e0 67 65 57 6f 72 6b 65 72 50 75 73 68 48 69 65 72  geWorkerPushHier
1a3f0 61 72 63 68 79 28 0a 20 20 4d 65 72 67 65 57 6f  archy(.  MergeWo
1a400 72 6b 65 72 20 2a 70 4d 57 2c 20 20 20 20 20 20  rker *pMW,      
1a410 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67           /* Merg
1a420 65 20 77 6f 72 6b 65 72 20 6f 62 6a 65 63 74 20  e worker object 
1a430 2a 2f 0a 20 20 69 6e 74 20 69 54 6f 70 69 63 2c  */.  int iTopic,
1a440 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a450 20 20 20 20 20 2f 2a 20 54 6f 70 69 63 20 76 61       /* Topic va
1a460 6c 75 65 20 66 6f 72 20 74 68 69 73 20 6b 65 79  lue for this key
1a470 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79   */.  void *pKey
1a480 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1a490 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
1a4a0 20 74 6f 20 6b 65 79 20 62 75 66 66 65 72 20 2a   to key buffer *
1a4b0 2f 0a 20 20 69 6e 74 20 6e 4b 65 79 20 20 20 20  /.  int nKey    
1a4c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a4d0 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 70      /* Size of p
1a4e0 4b 65 79 20 62 75 66 66 65 72 20 69 6e 20 62 79  Key buffer in by
1a4f0 74 65 73 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  tes */.){.  int 
1a500 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20  rc = LSM_OK;    
1a510 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
1a520 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20  eturn Code */.  
1a530 50 67 6e 6f 20 69 50 74 72 3b 20 20 20 20 20 20  Pgno iPtr;      
1a540 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a550 2f 2a 20 50 6f 69 6e 74 65 72 20 76 61 6c 75 65  /* Pointer value
1a560 20 74 6f 20 61 63 63 6f 6d 70 61 6e 79 20 70 4b   to accompany pK
1a570 65 79 2f 6e 4b 65 79 20 2a 2f 0a 0a 20 20 61 73  ey/nKey */..  as
1a580 73 65 72 74 28 20 70 4d 57 2d 3e 61 53 61 76 65  sert( pMW->aSave
1a590 5b 30 5d 2e 62 53 74 6f 72 65 3d 3d 30 20 29 3b  [0].bStore==0 );
1a5a0 0a 20 20 61 73 73 65 72 74 28 20 70 4d 57 2d 3e  .  assert( pMW->
1a5b0 61 53 61 76 65 5b 31 5d 2e 62 53 74 6f 72 65 3d  aSave[1].bStore=
1a5c0 3d 30 20 29 3b 0a 20 20 72 63 20 3d 20 6d 65 72  =0 );.  rc = mer
1a5d0 67 65 57 6f 72 6b 65 72 42 74 72 65 65 49 6e 64  geWorkerBtreeInd
1a5e0 69 72 65 63 74 28 70 4d 57 29 3b 0a 0a 20 20 2f  irect(pMW);..  /
1a5f0 2a 20 4f 62 74 61 69 6e 20 74 68 65 20 61 62 73  * Obtain the abs
1a600 6f 6c 75 74 65 20 70 6f 69 6e 74 65 72 20 76 61  olute pointer va
1a610 6c 75 65 20 74 6f 20 73 74 6f 72 65 20 61 6c 6f  lue to store alo
1a620 6e 67 20 77 69 74 68 20 74 68 65 20 6b 65 79 20  ng with the key 
1a630 69 6e 20 74 68 65 0a 20 20 2a 2a 20 70 61 67 65  in the.  ** page
1a640 20 62 6f 64 79 2e 20 54 68 69 73 20 70 6f 69 6e   body. This poin
1a650 74 65 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20  ter points to a 
1a660 70 61 67 65 20 74 68 61 74 20 63 6f 6e 74 61 69  page that contai
1a670 6e 73 20 6b 65 79 73 20 74 68 61 74 20 61 72 65  ns keys that are
1a680 0a 20 20 2a 2a 20 73 6d 61 6c 6c 65 72 20 74 68  .  ** smaller th
1a690 61 6e 20 70 4b 65 79 2f 6e 4b 65 79 2e 20 20 2a  an pKey/nKey.  *
1a6a0 2f 0a 20 20 69 50 74 72 20 3d 20 70 4d 57 2d 3e  /.  iPtr = pMW->
1a6b0 61 53 61 76 65 5b 30 5d 2e 69 50 67 6e 6f 3b 0a  aSave[0].iPgno;.
1a6c0 20 20 61 73 73 65 72 74 28 20 69 50 74 72 21 3d    assert( iPtr!=
1a6d0 30 20 29 3b 0a 0a 20 20 2f 2a 20 44 65 74 65 72  0 );..  /* Deter
1a6e0 6d 69 6e 65 20 69 66 20 74 68 65 20 69 6e 64 69  mine if the indi
1a6f0 72 65 63 74 20 66 6f 72 6d 61 74 20 73 68 6f 75  rect format shou
1a700 6c 64 20 62 65 20 75 73 65 64 2e 20 2a 2f 0a 20  ld be used. */. 
1a710 20 69 66 28 20 28 6e 4b 65 79 2a 34 20 3e 20 6c   if( (nKey*4 > l
1a720 73 6d 46 73 50 61 67 65 53 69 7a 65 28 70 4d 57  smFsPageSize(pMW
1a730 2d 3e 70 44 62 2d 3e 70 46 53 29 29 20 29 7b 0a  ->pDb->pFS)) ){.
1a740 20 20 20 20 70 4d 57 2d 3e 69 49 6e 64 69 72 65      pMW->iIndire
1a750 63 74 20 3d 20 69 50 74 72 3b 0a 20 20 20 20 70  ct = iPtr;.    p
1a760 4d 57 2d 3e 61 53 61 76 65 5b 31 5d 2e 62 53 74  MW->aSave[1].bSt
1a770 6f 72 65 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 65  ore = 1;.  }else
1a780 7b 0a 20 20 20 20 72 63 20 3d 20 6d 65 72 67 65  {.    rc = merge
1a790 57 6f 72 6b 65 72 42 74 72 65 65 57 72 69 74 65  WorkerBtreeWrite
1a7a0 28 0a 20 20 20 20 20 20 20 20 70 4d 57 2c 20 28  (.        pMW, (
1a7b0 75 38 29 28 69 54 6f 70 69 63 20 7c 20 4c 53 4d  u8)(iTopic | LSM
1a7c0 5f 53 45 50 41 52 41 54 4f 52 29 2c 20 69 50 74  _SEPARATOR), iPt
1a7d0 72 2c 20 30 2c 20 70 4b 65 79 2c 20 6e 4b 65 79  r, 0, pKey, nKey
1a7e0 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f  .    );.  }..  /
1a7f0 2a 20 45 6e 73 75 72 65 20 74 68 61 74 20 74 68  * Ensure that th
1a800 65 20 53 6f 72 74 65 64 52 75 6e 2e 69 52 6f 6f  e SortedRun.iRoo
1a810 74 20 66 69 65 6c 64 20 69 73 20 63 6f 72 72 65  t field is corre
1a820 63 74 2e 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20  ct. */.  return 
1a830 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  rc;.}..static in
1a840 74 20 6d 65 72 67 65 57 6f 72 6b 65 72 46 69 6e  t mergeWorkerFin
1a850 69 73 68 48 69 65 72 61 72 63 68 79 28 0a 20 20  ishHierarchy(.  
1a860 4d 65 72 67 65 57 6f 72 6b 65 72 20 2a 70 4d 57  MergeWorker *pMW
1a870 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a880 2f 2a 20 4d 65 72 67 65 20 77 6f 72 6b 65 72 20  /* Merge worker 
1a890 6f 62 6a 65 63 74 20 2a 2f 0a 29 7b 0a 20 20 69  object */.){.  i
1a8a0 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20  nt i;           
1a8b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1a8c0 2a 20 55 73 65 64 20 74 6f 20 6c 6f 6f 70 20 74  * Used to loop t
1a8d0 68 72 6f 75 67 68 20 61 70 48 69 65 72 5b 5d 20  hrough apHier[] 
1a8e0 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53  */.  int rc = LS
1a8f0 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  M_OK;           
1a900 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
1a910 6f 64 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 69 50  ode */.  Pgno iP
1a920 74 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  tr;             
1a930 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20           /* New 
1a940 72 69 67 68 74 2d 68 61 6e 64 2d 63 68 69 6c 64  right-hand-child
1a950 20 70 6f 69 6e 74 65 72 20 76 61 6c 75 65 20 2a   pointer value *
1a960 2f 0a 0a 20 20 69 50 74 72 20 3d 20 70 4d 57 2d  /..  iPtr = pMW-
1a970 3e 61 53 61 76 65 5b 30 5d 2e 69 50 67 6e 6f 3b  >aSave[0].iPgno;
1a980 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 4d  .  for(i=0; i<pM
1a990 57 2d 3e 68 69 65 72 2e 6e 48 69 65 72 20 26 26  W->hier.nHier &&
1a9a0 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 3b 20 69 2b 2b   rc==LSM_OK; i++
1a9b0 29 7b 0a 20 20 20 20 50 61 67 65 20 2a 70 50 67  ){.    Page *pPg
1a9c0 20 3d 20 70 4d 57 2d 3e 68 69 65 72 2e 61 70 48   = pMW->hier.apH
1a9d0 69 65 72 5b 69 5d 3b 0a 20 20 20 20 69 6e 74 20  ier[i];.    int 
1a9e0 6e 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20  nData;          
1a9f0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
1aa00 65 20 6f 66 20 61 44 61 74 61 5b 5d 20 69 6e 20  e of aData[] in 
1aa10 62 79 74 65 73 20 2a 2f 0a 20 20 20 20 75 38 20  bytes */.    u8 
1aa20 2a 61 44 61 74 61 3b 20 20 20 20 20 20 20 20 20  *aData;         
1aa30 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
1aa40 67 65 20 64 61 74 61 20 66 6f 72 20 70 50 67 20  ge data for pPg 
1aa50 2a 2f 0a 0a 20 20 20 20 61 44 61 74 61 20 3d 20  */..    aData = 
1aa60 66 73 50 61 67 65 44 61 74 61 28 70 50 67 2c 20  fsPageData(pPg, 
1aa70 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 6c 73 6d  &nData);.    lsm
1aa80 50 75 74 55 36 34 28 26 61 44 61 74 61 5b 53 45  PutU64(&aData[SE
1aa90 47 4d 45 4e 54 5f 50 4f 49 4e 54 45 52 5f 4f 46  GMENT_POINTER_OF
1aaa0 46 53 45 54 28 6e 44 61 74 61 29 5d 2c 20 69 50  FSET(nData)], iP
1aab0 74 72 29 3b 0a 0a 20 20 20 20 72 63 20 3d 20 6c  tr);..    rc = l
1aac0 73 6d 46 73 50 61 67 65 50 65 72 73 69 73 74 28  smFsPagePersist(
1aad0 70 50 67 29 3b 0a 20 20 20 20 69 50 74 72 20 3d  pPg);.    iPtr =
1aae0 20 6c 73 6d 46 73 50 61 67 65 4e 75 6d 62 65 72   lsmFsPageNumber
1aaf0 28 70 50 67 29 3b 0a 20 20 20 20 6c 73 6d 46 73  (pPg);.    lsmFs
1ab00 50 61 67 65 52 65 6c 65 61 73 65 28 70 50 67 29  PageRelease(pPg)
1ab10 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 4d 57  ;.  }..  if( pMW
1ab20 2d 3e 68 69 65 72 2e 6e 48 69 65 72 20 29 7b 0a  ->hier.nHier ){.
1ab30 20 20 20 20 70 4d 57 2d 3e 70 4c 65 76 65 6c 2d      pMW->pLevel-
1ab40 3e 6c 68 73 2e 69 52 6f 6f 74 20 3d 20 69 50 74  >lhs.iRoot = iPt
1ab50 72 3b 0a 20 20 20 20 6c 73 6d 46 72 65 65 28 70  r;.    lsmFree(p
1ab60 4d 57 2d 3e 70 44 62 2d 3e 70 45 6e 76 2c 20 70  MW->pDb->pEnv, p
1ab70 4d 57 2d 3e 68 69 65 72 2e 61 70 48 69 65 72 29  MW->hier.apHier)
1ab80 3b 0a 20 20 20 20 70 4d 57 2d 3e 68 69 65 72 2e  ;.    pMW->hier.
1ab90 61 70 48 69 65 72 20 3d 20 30 3b 0a 20 20 20 20  apHier = 0;.    
1aba0 70 4d 57 2d 3e 68 69 65 72 2e 6e 48 69 65 72 20  pMW->hier.nHier 
1abb0 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  = 0;.  }..  retu
1abc0 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
1abd0 20 69 6e 74 20 6d 65 72 67 65 57 6f 72 6b 65 72   int mergeWorker
1abe0 41 64 64 50 61 64 64 69 6e 67 28 0a 20 20 4d 65  AddPadding(.  Me
1abf0 72 67 65 57 6f 72 6b 65 72 20 2a 70 4d 57 20 20  rgeWorker *pMW  
1ac00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1ac10 20 4d 65 72 67 65 20 77 6f 72 6b 65 72 20 6f 62   Merge worker ob
1ac20 6a 65 63 74 20 2a 2f 0a 29 7b 0a 20 20 46 69 6c  ject */.){.  Fil
1ac30 65 53 79 73 74 65 6d 20 2a 70 46 53 20 3d 20 70  eSystem *pFS = p
1ac40 4d 57 2d 3e 70 44 62 2d 3e 70 46 53 3b 0a 20 20  MW->pDb->pFS;.  
1ac50 72 65 74 75 72 6e 20 6c 73 6d 46 73 53 6f 72 74  return lsmFsSort
1ac60 65 64 50 61 64 64 69 6e 67 28 70 46 53 2c 20 70  edPadding(pFS, p
1ac70 4d 57 2d 3e 70 44 62 2d 3e 70 57 6f 72 6b 65 72  MW->pDb->pWorker
1ac80 2c 20 26 70 4d 57 2d 3e 70 4c 65 76 65 6c 2d 3e  , &pMW->pLevel->
1ac90 6c 68 73 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  lhs);.}../*.** R
1aca0 65 6c 65 61 73 65 20 61 6c 6c 20 70 61 67 65 20  elease all page 
1acb0 72 65 66 65 72 65 6e 63 65 73 20 63 75 72 72 65  references curre
1acc0 6e 74 6c 79 20 68 65 6c 64 20 62 79 20 74 68 65  ntly held by the
1acd0 20 6d 65 72 67 65 2d 77 6f 72 6b 65 72 20 70 61   merge-worker pa
1ace0 73 73 65 64 0a 2a 2a 20 61 73 20 74 68 65 20 6f  ssed.** as the o
1acf0 6e 6c 79 20 61 72 67 75 6d 65 6e 74 2e 20 55 6e  nly argument. Un
1ad00 6c 65 73 73 20 61 6e 20 65 72 72 6f 72 20 68 61  less an error ha
1ad10 73 20 6f 63 63 75 72 72 65 64 2c 20 61 6c 6c 20  s occurred, all 
1ad20 70 61 67 65 73 20 68 61 76 65 0a 2a 2a 20 61 6c  pages have.** al
1ad30 72 65 61 64 79 20 62 65 65 6e 20 72 65 6c 65 61  ready been relea
1ad40 73 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  sed..*/.static v
1ad50 6f 69 64 20 6d 65 72 67 65 57 6f 72 6b 65 72 52  oid mergeWorkerR
1ad60 65 6c 65 61 73 65 41 6c 6c 28 4d 65 72 67 65 57  eleaseAll(MergeW
1ad70 6f 72 6b 65 72 20 2a 70 4d 57 29 7b 0a 20 20 69  orker *pMW){.  i
1ad80 6e 74 20 69 3b 0a 20 20 6c 73 6d 46 73 50 61 67  nt i;.  lsmFsPag
1ad90 65 52 65 6c 65 61 73 65 28 70 4d 57 2d 3e 70 50  eRelease(pMW->pP
1ada0 61 67 65 29 3b 0a 20 20 70 4d 57 2d 3e 70 50 61  age);.  pMW->pPa
1adb0 67 65 20 3d 20 30 3b 0a 0a 20 20 66 6f 72 28 69  ge = 0;..  for(i
1adc0 3d 30 3b 20 69 3c 70 4d 57 2d 3e 68 69 65 72 2e  =0; i<pMW->hier.
1add0 6e 48 69 65 72 3b 20 69 2b 2b 29 7b 0a 20 20 20  nHier; i++){.   
1ade0 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61 73   lsmFsPageReleas
1adf0 65 28 70 4d 57 2d 3e 68 69 65 72 2e 61 70 48 69  e(pMW->hier.apHi
1ae00 65 72 5b 69 5d 29 3b 0a 20 20 20 20 70 4d 57 2d  er[i]);.    pMW-
1ae10 3e 68 69 65 72 2e 61 70 48 69 65 72 5b 69 5d 20  >hier.apHier[i] 
1ae20 3d 20 30 3b 0a 20 20 7d 0a 20 20 6c 73 6d 46 72  = 0;.  }.  lsmFr
1ae30 65 65 28 70 4d 57 2d 3e 70 44 62 2d 3e 70 45 6e  ee(pMW->pDb->pEn
1ae40 76 2c 20 70 4d 57 2d 3e 68 69 65 72 2e 61 70 48  v, pMW->hier.apH
1ae50 69 65 72 29 3b 0a 20 20 70 4d 57 2d 3e 68 69 65  ier);.  pMW->hie
1ae60 72 2e 61 70 48 69 65 72 20 3d 20 30 3b 0a 20 20  r.apHier = 0;.  
1ae70 70 4d 57 2d 3e 68 69 65 72 2e 6e 48 69 65 72 20  pMW->hier.nHier 
1ae80 3d 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  = 0;.}..static i
1ae90 6e 74 20 6b 65 79 73 7a 54 6f 53 6b 69 70 28 46  nt keyszToSkip(F
1aea0 69 6c 65 53 79 73 74 65 6d 20 2a 70 46 53 2c 20  ileSystem *pFS, 
1aeb0 69 6e 74 20 6e 4b 65 79 29 7b 0a 20 20 69 6e 74  int nKey){.  int
1aec0 20 6e 50 67 73 7a 3b 20 20 20 20 20 20 20 20 20   nPgsz;         
1aed0 20 20 20 20 20 20 20 2f 2a 20 4e 6f 6d 69 6e 61         /* Nomina
1aee0 6c 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20  l database page 
1aef0 73 69 7a 65 20 2a 2f 0a 20 20 6e 50 67 73 7a 20  size */.  nPgsz 
1af00 3d 20 6c 73 6d 46 73 50 61 67 65 53 69 7a 65 28  = lsmFsPageSize(
1af10 70 46 53 29 3b 0a 20 20 72 65 74 75 72 6e 20 4c  pFS);.  return L
1af20 53 4d 5f 4d 49 4e 28 28 28 6e 4b 65 79 20 2a 20  SM_MIN(((nKey * 
1af30 34 29 20 2f 20 6e 50 67 73 7a 29 2c 20 33 29 3b  4) / nPgsz), 3);
1af40 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6c 65 61 73  .}../*.** Releas
1af50 65 20 74 68 65 20 72 65 66 65 72 65 6e 63 65 20  e the reference 
1af60 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20 6f  to the current o
1af70 75 74 70 75 74 20 70 61 67 65 20 6f 66 20 6d 65  utput page of me
1af80 72 67 65 2d 77 6f 72 6b 65 72 20 2a 70 4d 57 0a  rge-worker *pMW.
1af90 2a 2a 20 28 72 65 66 65 72 65 6e 63 65 20 70 4d  ** (reference pM
1afa0 57 2d 3e 70 50 61 67 65 29 2e 20 53 65 74 20 74  W->pPage). Set t
1afb0 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20 76  he page number v
1afc0 61 6c 75 65 73 20 69 6e 20 61 53 61 76 65 5b 5d  alues in aSave[]
1afd0 20 61 73 20 0a 2a 2a 20 72 65 71 75 69 72 65 64   as .** required
1afe0 20 28 73 65 65 20 63 6f 6d 6d 65 6e 74 73 20 61   (see comments a
1aff0 62 6f 76 65 20 73 74 72 75 63 74 20 4d 65 72 67  bove struct Merg
1b000 65 57 6f 72 6b 65 72 20 66 6f 72 20 64 65 74 61  eWorker for deta
1b010 69 6c 73 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ils)..*/.static 
1b020 69 6e 74 20 6d 65 72 67 65 57 6f 72 6b 65 72 50  int mergeWorkerP
1b030 65 72 73 69 73 74 41 6e 64 52 65 6c 65 61 73 65  ersistAndRelease
1b040 28 4d 65 72 67 65 57 6f 72 6b 65 72 20 2a 70 4d  (MergeWorker *pM
1b050 57 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  W){.  int rc;.  
1b060 69 6e 74 20 69 3b 0a 0a 20 20 61 73 73 65 72 74  int i;..  assert
1b070 28 20 70 4d 57 2d 3e 70 50 61 67 65 20 7c 7c 20  ( pMW->pPage || 
1b080 28 70 4d 57 2d 3e 61 53 61 76 65 5b 30 5d 2e 62  (pMW->aSave[0].b
1b090 53 74 6f 72 65 3d 3d 30 20 26 26 20 70 4d 57 2d  Store==0 && pMW-
1b0a0 3e 61 53 61 76 65 5b 31 5d 2e 62 53 74 6f 72 65  >aSave[1].bStore
1b0b0 3d 3d 30 29 20 29 3b 0a 0a 20 20 2f 2a 20 50 65  ==0) );..  /* Pe
1b0c0 72 73 69 73 74 20 74 68 65 20 70 61 67 65 20 2a  rsist the page *
1b0d0 2f 0a 20 20 72 63 20 3d 20 6c 73 6d 46 73 50 61  /.  rc = lsmFsPa
1b0e0 67 65 50 65 72 73 69 73 74 28 70 4d 57 2d 3e 70  gePersist(pMW->p
1b0f0 50 61 67 65 29 3b 0a 0a 20 20 2f 2a 20 49 66 20  Page);..  /* If 
1b100 72 65 71 75 69 72 65 64 2c 20 73 61 76 65 20 74  required, save t
1b110 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 2e 20  he page number. 
1b120 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  */.  for(i=0; i<
1b130 32 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  2; i++){.    if(
1b140 20 70 4d 57 2d 3e 61 53 61 76 65 5b 69 5d 2e 62   pMW->aSave[i].b
1b150 53 74 6f 72 65 20 29 7b 0a 20 20 20 20 20 20 70  Store ){.      p
1b160 4d 57 2d 3e 61 53 61 76 65 5b 69 5d 2e 69 50 67  MW->aSave[i].iPg
1b170 6e 6f 20 3d 20 6c 73 6d 46 73 50 61 67 65 4e 75  no = lsmFsPageNu
1b180 6d 62 65 72 28 70 4d 57 2d 3e 70 50 61 67 65 29  mber(pMW->pPage)
1b190 3b 0a 20 20 20 20 20 20 70 4d 57 2d 3e 61 53 61  ;.      pMW->aSa
1b1a0 76 65 5b 69 5d 2e 62 53 74 6f 72 65 20 3d 20 30  ve[i].bStore = 0
1b1b0 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  ;.    }.  }..  /
1b1c0 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20 63 6f  * Release the co
1b1d0 6d 70 6c 65 74 65 64 20 6f 75 74 70 75 74 20 70  mpleted output p
1b1e0 61 67 65 2e 20 2a 2f 0a 20 20 6c 73 6d 46 73 50  age. */.  lsmFsP
1b1f0 61 67 65 52 65 6c 65 61 73 65 28 70 4d 57 2d 3e  ageRelease(pMW->
1b200 70 50 61 67 65 29 3b 0a 20 20 70 4d 57 2d 3e 70  pPage);.  pMW->p
1b210 50 61 67 65 20 3d 20 30 3b 0a 20 20 72 65 74 75  Page = 0;.  retu
1b220 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
1b230 41 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20 6e  Advance to the n
1b240 65 78 74 20 70 61 67 65 20 6f 66 20 61 6e 20 6f  ext page of an o
1b250 75 74 70 75 74 20 72 75 6e 20 62 65 69 6e 67 20  utput run being 
1b260 70 6f 70 75 6c 61 74 65 64 20 62 79 20 6d 65 72  populated by mer
1b270 67 65 2d 77 6f 72 6b 65 72 0a 2a 2a 20 70 4d 57  ge-worker.** pMW
1b280 2e 20 54 68 65 20 66 6f 6f 74 65 72 20 6f 66 20  . The footer of 
1b290 74 68 65 20 6e 65 77 20 70 61 67 65 20 69 73 20  the new page is 
1b2a0 69 6e 69 74 69 61 6c 69 7a 65 64 20 74 6f 20 69  initialized to i
1b2b0 6e 64 69 63 61 74 65 20 74 68 61 74 20 69 74 20  ndicate that it 
1b2c0 63 6f 6e 74 61 69 6e 73 0a 2a 2a 20 7a 65 72 6f  contains.** zero
1b2d0 20 72 65 63 6f 72 64 73 2e 20 54 68 65 20 66 6c   records. The fl
1b2e0 61 67 73 20 66 69 65 6c 64 20 69 73 20 63 6c 65  ags field is cle
1b2f0 61 72 65 64 2e 20 54 68 65 20 70 61 67 65 20 66  ared. The page f
1b300 6f 6f 74 65 72 20 70 6f 69 6e 74 65 72 20 66 69  ooter pointer fi
1b310 65 6c 64 0a 2a 2a 20 69 73 20 73 65 74 20 74 6f  eld.** is set to
1b320 20 69 46 50 74 72 2e 0a 2a 2a 0a 2a 2a 20 49 66   iFPtr..**.** If
1b330 20 73 75 63 63 65 73 73 66 75 6c 2c 20 4c 53 4d   successful, LSM
1b340 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 2e  _OK is returned.
1b350 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6e 20 65   Otherwise, an e
1b360 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a 73 74  rror code..*/.st
1b370 61 74 69 63 20 69 6e 74 20 6d 65 72 67 65 57 6f  atic int mergeWo
1b380 72 6b 65 72 4e 65 78 74 50 61 67 65 28 0a 20 20  rkerNextPage(.  
1b390 4d 65 72 67 65 57 6f 72 6b 65 72 20 2a 70 4d 57  MergeWorker *pMW
1b3a0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1b3b0 2f 2a 20 4d 65 72 67 65 20 77 6f 72 6b 65 72 20  /* Merge worker 
1b3c0 6f 62 6a 65 63 74 20 74 6f 20 61 70 70 65 6e 64  object to append
1b3d0 20 70 61 67 65 20 74 6f 20 2a 2f 0a 20 20 50 67   page to */.  Pg
1b3e0 6e 6f 20 69 46 50 74 72 20 20 20 20 20 20 20 20  no iFPtr        
1b3f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1b400 20 50 6f 69 6e 74 65 72 20 76 61 6c 75 65 20 66   Pointer value f
1b410 6f 72 20 66 6f 6f 74 65 72 20 6f 66 20 6e 65 77  or footer of new
1b420 20 70 61 67 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e   page */.){.  in
1b430 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20  t rc = LSM_OK;  
1b440 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1b450 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
1b460 20 20 50 61 67 65 20 2a 70 4e 65 78 74 20 3d 20    Page *pNext = 
1b470 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
1b480 20 20 2f 2a 20 4e 65 77 20 70 61 67 65 20 61 70    /* New page ap
1b490 70 65 6e 64 65 64 20 74 6f 20 72 75 6e 20 2a 2f  pended to run */
1b4a0 0a 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62 20 3d  .  lsm_db *pDb =
1b4b0 20 70 4d 57 2d 3e 70 44 62 3b 20 20 20 20 20 20   pMW->pDb;      
1b4c0 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68     /* Database h
1b4d0 61 6e 64 6c 65 20 2a 2f 0a 0a 20 20 72 63 20 3d  andle */..  rc =
1b4e0 20 6c 73 6d 46 73 53 6f 72 74 65 64 41 70 70 65   lsmFsSortedAppe
1b4f0 6e 64 28 70 44 62 2d 3e 70 46 53 2c 20 70 44 62  nd(pDb->pFS, pDb
1b500 2d 3e 70 57 6f 72 6b 65 72 2c 20 70 4d 57 2d 3e  ->pWorker, pMW->
1b510 70 4c 65 76 65 6c 2c 20 30 2c 20 26 70 4e 65 78  pLevel, 0, &pNex
1b520 74 29 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63  t);.  assert( rc
1b530 20 7c 7c 20 70 4d 57 2d 3e 70 4c 65 76 65 6c 2d   || pMW->pLevel-
1b540 3e 6c 68 73 2e 69 46 69 72 73 74 3e 30 20 7c 7c  >lhs.iFirst>0 ||
1b550 20 70 4d 57 2d 3e 70 44 62 2d 3e 63 6f 6d 70 72   pMW->pDb->compr
1b560 65 73 73 2e 78 43 6f 6d 70 72 65 73 73 20 29 3b  ess.xCompress );
1b570 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f  ..  if( rc==LSM_
1b580 4f 4b 20 29 7b 0a 20 20 20 20 75 38 20 2a 61 44  OK ){.    u8 *aD
1b590 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20  ata;            
1b5a0 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 20          /* Data 
1b5b0 62 75 66 66 65 72 20 62 65 6c 6f 6e 67 69 6e 67  buffer belonging
1b5c0 20 74 6f 20 70 61 67 65 20 70 4e 65 78 74 20 2a   to page pNext *
1b5d0 2f 0a 20 20 20 20 69 6e 74 20 6e 44 61 74 61 3b  /.    int nData;
1b5e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b5f0 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61      /* Size of a
1b600 44 61 74 61 5b 5d 20 69 6e 20 62 79 74 65 73 20  Data[] in bytes 
1b610 2a 2f 0a 0a 20 20 20 20 72 63 20 3d 20 6d 65 72  */..    rc = mer
1b620 67 65 57 6f 72 6b 65 72 50 65 72 73 69 73 74 41  geWorkerPersistA
1b630 6e 64 52 65 6c 65 61 73 65 28 70 4d 57 29 3b 0a  ndRelease(pMW);.
1b640 0a 20 20 20 20 70 4d 57 2d 3e 70 50 61 67 65 20  .    pMW->pPage 
1b650 3d 20 70 4e 65 78 74 3b 0a 20 20 20 20 70 4d 57  = pNext;.    pMW
1b660 2d 3e 70 4c 65 76 65 6c 2d 3e 70 4d 65 72 67 65  ->pLevel->pMerge
1b670 2d 3e 69 4f 75 74 70 75 74 4f 66 66 20 3d 20 30  ->iOutputOff = 0
1b680 3b 0a 20 20 20 20 61 44 61 74 61 20 3d 20 66 73  ;.    aData = fs
1b690 50 61 67 65 44 61 74 61 28 70 4e 65 78 74 2c 20  PageData(pNext, 
1b6a0 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 6c 73 6d  &nData);.    lsm
1b6b0 50 75 74 55 31 36 28 26 61 44 61 74 61 5b 53 45  PutU16(&aData[SE
1b6c0 47 4d 45 4e 54 5f 4e 52 45 43 4f 52 44 5f 4f 46  GMENT_NRECORD_OF
1b6d0 46 53 45 54 28 6e 44 61 74 61 29 5d 2c 20 30 29  FSET(nData)], 0)
1b6e0 3b 0a 20 20 20 20 6c 73 6d 50 75 74 55 31 36 28  ;.    lsmPutU16(
1b6f0 26 61 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f 46  &aData[SEGMENT_F
1b700 4c 41 47 53 5f 4f 46 46 53 45 54 28 6e 44 61 74  LAGS_OFFSET(nDat
1b710 61 29 5d 2c 20 30 29 3b 0a 20 20 20 20 6c 73 6d  a)], 0);.    lsm
1b720 50 75 74 55 36 34 28 26 61 44 61 74 61 5b 53 45  PutU64(&aData[SE
1b730 47 4d 45 4e 54 5f 50 4f 49 4e 54 45 52 5f 4f 46  GMENT_POINTER_OF
1b740 46 53 45 54 28 6e 44 61 74 61 29 5d 2c 20 69 46  FSET(nData)], iF
1b750 50 74 72 29 3b 0a 20 20 20 20 70 4d 57 2d 3e 6e  Ptr);.    pMW->n
1b760 57 6f 72 6b 2b 2b 3b 0a 20 20 7d 0a 0a 20 20 72  Work++;.  }..  r
1b770 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
1b780 2a 2a 20 57 72 69 74 65 20 61 20 62 6c 6f 62 20  ** Write a blob 
1b790 6f 66 20 64 61 74 61 20 69 6e 74 6f 20 61 6e 20  of data into an 
1b7a0 6f 75 74 70 75 74 20 73 65 67 6d 65 6e 74 20 62  output segment b
1b7b0 65 69 6e 67 20 70 6f 70 75 6c 61 74 65 64 20 62  eing populated b
1b7c0 79 20 61 20 0a 2a 2a 20 6d 65 72 67 65 2d 77 6f  y a .** merge-wo
1b7d0 72 6b 65 72 20 6f 62 6a 65 63 74 2e 20 49 66 20  rker object. If 
1b7e0 61 72 67 75 6d 65 6e 74 20 62 53 65 70 20 69 73  argument bSep is
1b7f0 20 74 72 75 65 2c 20 77 72 69 74 65 20 69 6e 74   true, write int
1b800 6f 20 74 68 65 20 73 65 70 61 72 61 74 6f 72 73  o the separators
1b810 0a 2a 2a 20 61 72 72 61 79 2e 20 4f 74 68 65 72  .** array. Other
1b820 77 69 73 65 2c 20 74 68 65 20 6d 61 69 6e 20 61  wise, the main a
1b830 72 72 61 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  rray..**.** This
1b840 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65   function is use
1b850 64 20 74 6f 20 77 72 69 74 65 20 74 68 65 20 62  d to write the b
1b860 6c 6f 62 73 20 6f 66 20 64 61 74 61 20 66 6f 72  lobs of data for
1b870 20 6b 65 79 73 20 61 6e 64 20 76 61 6c 75 65 73   keys and values
1b880 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
1b890 6d 65 72 67 65 57 6f 72 6b 65 72 44 61 74 61 28  mergeWorkerData(
1b8a0 0a 20 20 4d 65 72 67 65 57 6f 72 6b 65 72 20 2a  .  MergeWorker *
1b8b0 70 4d 57 2c 20 20 20 20 20 20 20 20 20 20 20 20  pMW,            
1b8c0 20 20 20 2f 2a 20 4d 65 72 67 65 20 77 6f 72 6b     /* Merge work
1b8d0 65 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69  er object */.  i
1b8e0 6e 74 20 62 53 65 70 2c 20 20 20 20 20 20 20 20  nt bSep,        
1b8f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1b900 2a 20 54 72 75 65 20 74 6f 20 77 72 69 74 65 20  * True to write 
1b910 74 6f 20 73 65 70 61 72 61 74 6f 72 73 20 72 75  to separators ru
1b920 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 46 50 74 72  n */.  int iFPtr
1b930 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1b940 20 20 20 20 20 20 20 2f 2a 20 46 6f 6f 74 65 72         /* Footer
1b950 20 70 74 72 20 66 6f 72 20 6e 65 77 20 70 61 67   ptr for new pag
1b960 65 73 20 2a 2f 0a 20 20 75 38 20 2a 61 57 72 69  es */.  u8 *aWri
1b970 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  te,             
1b980 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65          /* Write
1b990 20 64 61 74 61 20 66 72 6f 6d 20 74 68 69 73 20   data from this 
1b9a0 62 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20  buffer */.  int 
1b9b0 6e 57 72 69 74 65 20 20 20 20 20 20 20 20 20 20  nWrite          
1b9c0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
1b9d0 69 7a 65 20 6f 66 20 61 57 72 69 74 65 5b 5d 20  ize of aWrite[] 
1b9e0 69 6e 20 62 79 74 65 73 20 2a 2f 0a 29 7b 0a 20  in bytes */.){. 
1b9f0 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
1ba00 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1ba10 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
1ba20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 6d 20 3d 20  */.  int nRem = 
1ba30 6e 57 72 69 74 65 3b 20 20 20 20 20 20 20 20 20  nWrite;         
1ba40 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
1ba50 66 20 62 79 74 65 73 20 73 74 69 6c 6c 20 74 6f  f bytes still to
1ba60 20 77 72 69 74 65 20 2a 2f 0a 0a 20 20 77 68 69   write */..  whi
1ba70 6c 65 28 20 6e 52 65 6d 3e 30 20 29 7b 0a 20 20  le( nRem>0 ){.  
1ba80 20 20 4d 65 72 67 65 20 2a 70 4d 65 72 67 65 20    Merge *pMerge 
1ba90 3d 20 70 4d 57 2d 3e 70 4c 65 76 65 6c 2d 3e 70  = pMW->pLevel->p
1baa0 4d 65 72 67 65 3b 0a 20 20 20 20 69 6e 74 20 6e  Merge;.    int n
1bab0 43 6f 70 79 3b 20 20 20 20 20 20 20 20 20 20 20  Copy;           
1bac0 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
1bad0 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20 63  er of bytes to c
1bae0 6f 70 79 20 2a 2f 0a 20 20 20 20 75 38 20 2a 61  opy */.    u8 *a
1baf0 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20  Data;           
1bb00 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
1bb10 74 65 72 20 74 6f 20 62 75 66 66 65 72 20 6f 66  ter to buffer of
1bb20 20 63 75 72 72 65 6e 74 20 6f 75 74 70 75 74 20   current output 
1bb30 70 61 67 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20  page */.    int 
1bb40 6e 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20  nData;          
1bb50 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
1bb60 65 20 6f 66 20 61 44 61 74 61 5b 5d 20 69 6e 20  e of aData[] in 
1bb70 62 79 74 65 73 20 2a 2f 0a 20 20 20 20 69 6e 74  bytes */.    int
1bb80 20 6e 52 65 63 3b 20 20 20 20 20 20 20 20 20 20   nRec;          
1bb90 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
1bba0 6d 62 65 72 20 6f 66 20 72 65 63 6f 72 64 73 20  mber of records 
1bbb0 6f 6e 20 63 75 72 72 65 6e 74 20 6f 75 74 70 75  on current outpu
1bbc0 74 20 70 61 67 65 20 2a 2f 0a 20 20 20 20 69 6e  t page */.    in
1bbd0 74 20 69 4f 66 66 3b 20 20 20 20 20 20 20 20 20  t iOff;         
1bbe0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
1bbf0 66 66 73 65 74 20 69 6e 20 61 44 61 74 61 5b 5d  ffset in aData[]
1bc00 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a   to write to */.
1bc10 0a 20 20 20 20 61 73 73 65 72 74 28 20 6c 73 6d  .    assert( lsm
1bc20 46 73 50 61 67 65 57 72 69 74 61 62 6c 65 28 70  FsPageWritable(p
1bc30 4d 57 2d 3e 70 50 61 67 65 29 20 29 3b 0a 20 20  MW->pPage) );.  
1bc40 20 0a 20 20 20 20 61 44 61 74 61 20 3d 20 66 73   .    aData = fs
1bc50 50 61 67 65 44 61 74 61 28 70 4d 57 2d 3e 70 50  PageData(pMW->pP
1bc60 61 67 65 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20  age, &nData);.  
1bc70 20 20 6e 52 65 63 20 3d 20 70 61 67 65 47 65 74    nRec = pageGet
1bc80 4e 52 65 63 28 61 44 61 74 61 2c 20 6e 44 61 74  NRec(aData, nDat
1bc90 61 29 3b 0a 20 20 20 20 69 4f 66 66 20 3d 20 70  a);.    iOff = p
1bca0 4d 65 72 67 65 2d 3e 69 4f 75 74 70 75 74 4f 66  Merge->iOutputOf
1bcb0 66 3b 0a 20 20 20 20 6e 43 6f 70 79 20 3d 20 4c  f;.    nCopy = L
1bcc0 53 4d 5f 4d 49 4e 28 6e 52 65 6d 2c 20 53 45 47  SM_MIN(nRem, SEG
1bcd0 4d 45 4e 54 5f 45 4f 46 28 6e 44 61 74 61 2c 20  MENT_EOF(nData, 
1bce0 6e 52 65 63 29 20 2d 20 69 4f 66 66 29 3b 0a 0a  nRec) - iOff);..
1bcf0 20 20 20 20 6d 65 6d 63 70 79 28 26 61 44 61 74      memcpy(&aDat
1bd00 61 5b 69 4f 66 66 5d 2c 20 26 61 57 72 69 74 65  a[iOff], &aWrite
1bd10 5b 6e 57 72 69 74 65 2d 6e 52 65 6d 5d 2c 20 6e  [nWrite-nRem], n
1bd20 43 6f 70 79 29 3b 0a 20 20 20 20 6e 52 65 6d 20  Copy);.    nRem 
1bd30 2d 3d 20 6e 43 6f 70 79 3b 0a 0a 20 20 20 20 69  -= nCopy;..    i
1bd40 66 28 20 6e 52 65 6d 3e 30 20 29 7b 0a 20 20 20  f( nRem>0 ){.   
1bd50 20 20 20 72 63 20 3d 20 6d 65 72 67 65 57 6f 72     rc = mergeWor
1bd60 6b 65 72 4e 65 78 74 50 61 67 65 28 70 4d 57 2c  kerNextPage(pMW,
1bd70 20 69 46 50 74 72 29 3b 0a 20 20 20 20 7d 65 6c   iFPtr);.    }el
1bd80 73 65 7b 0a 20 20 20 20 20 20 70 4d 65 72 67 65  se{.      pMerge
1bd90 2d 3e 69 4f 75 74 70 75 74 4f 66 66 20 3d 20 69  ->iOutputOff = i
1bda0 4f 66 66 20 2b 20 6e 43 6f 70 79 3b 0a 20 20 20  Off + nCopy;.   
1bdb0 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
1bdc0 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 54   rc;.}.../*.** T
1bdd0 68 65 20 4d 65 72 67 65 57 6f 72 6b 65 72 20 70  he MergeWorker p
1bde0 61 73 73 65 64 20 61 73 20 74 68 65 20 6f 6e 6c  assed as the onl
1bdf0 79 20 61 72 67 75 6d 65 6e 74 20 69 73 20 77 6f  y argument is wo
1be00 72 6b 69 6e 67 20 74 6f 20 6d 65 72 67 65 20 74  rking to merge t
1be10 77 6f 20 6f 72 0a 2a 2a 20 6d 6f 72 65 20 65 78  wo or.** more ex
1be20 69 73 74 69 6e 67 20 73 65 67 6d 65 6e 74 73 20  isting segments 
1be30 74 6f 67 65 74 68 65 72 20 28 6e 6f 74 20 74 6f  together (not to
1be40 20 66 6c 75 73 68 20 61 6e 20 69 6e 2d 6d 65 6d   flush an in-mem
1be50 6f 72 79 20 74 72 65 65 29 2e 20 49 74 0a 2a 2a  ory tree). It.**
1be60 20 68 61 73 20 6e 6f 74 20 79 65 74 20 77 72 69   has not yet wri
1be70 74 74 65 6e 20 74 68 65 20 66 69 72 73 74 20 6b  tten the first k
1be80 65 79 20 74 6f 20 74 68 65 20 66 69 72 73 74 20  ey to the first 
1be90 70 61 67 65 20 6f 66 20 74 68 65 20 6f 75 74 70  page of the outp
1bea0 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ut..*/.static in
1beb0 74 20 6d 65 72 67 65 57 6f 72 6b 65 72 46 69 72  t mergeWorkerFir
1bec0 73 74 50 61 67 65 28 4d 65 72 67 65 57 6f 72 6b  stPage(MergeWork
1bed0 65 72 20 2a 70 4d 57 29 7b 0a 20 20 69 6e 74 20  er *pMW){.  int 
1bee0 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20  rc = LSM_OK;    
1bef0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
1bf00 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
1bf10 50 61 67 65 20 2a 70 50 67 20 3d 20 30 3b 20 20  Page *pPg = 0;  
1bf20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bf30 2f 2a 20 46 69 72 73 74 20 70 61 67 65 20 6f 66  /* First page of
1bf40 20 72 75 6e 20 70 53 65 67 20 2a 2f 0a 20 20 69   run pSeg */.  i
1bf50 6e 74 20 69 46 50 74 72 20 3d 20 30 3b 20 20 20  nt iFPtr = 0;   
1bf60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1bf70 2a 20 50 6f 69 6e 74 65 72 20 76 61 6c 75 65 20  * Pointer value 
1bf80 72 65 61 64 20 66 72 6f 6d 20 66 6f 6f 74 65 72  read from footer
1bf90 20 6f 66 20 70 50 67 20 2a 2f 0a 20 20 4d 75 6c   of pPg */.  Mul
1bfa0 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d  tiCursor *pCsr =
1bfb0 20 70 4d 57 2d 3e 70 43 73 72 3b 0a 0a 20 20 61   pMW->pCsr;..  a
1bfc0 73 73 65 72 74 28 20 70 4d 57 2d 3e 70 50 61 67  ssert( pMW->pPag
1bfd0 65 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 70  e==0 );..  if( p
1bfe0 43 73 72 2d 3e 70 42 74 43 73 72 20 29 7b 0a 20  Csr->pBtCsr ){. 
1bff0 20 20 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a     rc = LSM_OK;.
1c000 20 20 20 20 69 46 50 74 72 20 3d 20 70 4d 57 2d      iFPtr = pMW-
1c010 3e 70 4c 65 76 65 6c 2d 3e 70 4e 65 78 74 2d 3e  >pLevel->pNext->
1c020 6c 68 73 2e 69 46 69 72 73 74 3b 0a 20 20 7d 65  lhs.iFirst;.  }e
1c030 6c 73 65 20 69 66 28 20 70 43 73 72 2d 3e 6e 50  lse if( pCsr->nP
1c040 74 72 3e 30 20 29 7b 0a 20 20 20 20 53 65 67 6d  tr>0 ){.    Segm
1c050 65 6e 74 20 2a 70 53 65 67 3b 0a 20 20 20 20 70  ent *pSeg;.    p
1c060 53 65 67 20 3d 20 70 43 73 72 2d 3e 61 50 74 72  Seg = pCsr->aPtr
1c070 5b 70 43 73 72 2d 3e 6e 50 74 72 2d 31 5d 2e 70  [pCsr->nPtr-1].p
1c080 53 65 67 3b 0a 20 20 20 20 72 63 20 3d 20 6c 73  Seg;.    rc = ls
1c090 6d 46 73 44 62 50 61 67 65 47 65 74 28 70 4d 57  mFsDbPageGet(pMW
1c0a0 2d 3e 70 44 62 2d 3e 70 46 53 2c 20 70 53 65 67  ->pDb->pFS, pSeg
1c0b0 2c 20 70 53 65 67 2d 3e 69 46 69 72 73 74 2c 20  , pSeg->iFirst, 
1c0c0 26 70 50 67 29 3b 0a 20 20 20 20 69 66 28 20 72  &pPg);.    if( r
1c0d0 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
1c0e0 20 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20 20     u8 *aData;   
1c0f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c100 20 2f 2a 20 42 75 66 66 65 72 20 66 6f 72 20 70   /* Buffer for p
1c110 61 67 65 20 70 50 67 20 2a 2f 0a 20 20 20 20 20  age pPg */.     
1c120 20 69 6e 74 20 6e 44 61 74 61 3b 20 20 20 20 20   int nData;     
1c130 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1c140 2a 20 53 69 7a 65 20 6f 66 20 61 44 61 74 61 5b  * Size of aData[
1c150 5d 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  ] in bytes */.  
1c160 20 20 20 20 61 44 61 74 61 20 3d 20 66 73 50 61      aData = fsPa
1c170 67 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44 61  geData(pPg, &nDa
1c180 74 61 29 3b 0a 20 20 20 20 20 20 69 46 50 74 72  ta);.      iFPtr
1c190 20 3d 20 70 61 67 65 47 65 74 50 74 72 28 61 44   = pageGetPtr(aD
1c1a0 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20  ata, nData);.   
1c1b0 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65     lsmFsPageRele
1c1c0 61 73 65 28 70 50 67 29 3b 0a 20 20 20 20 7d 0a  ase(pPg);.    }.
1c1d0 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c    }..  if( rc==L
1c1e0 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  SM_OK ){.    rc 
1c1f0 3d 20 6d 65 72 67 65 57 6f 72 6b 65 72 4e 65 78  = mergeWorkerNex
1c200 74 50 61 67 65 28 70 4d 57 2c 20 69 46 50 74 72  tPage(pMW, iFPtr
1c210 29 3b 0a 20 20 20 20 69 66 28 20 70 43 73 72 2d  );.    if( pCsr-
1c220 3e 70 50 72 65 76 4d 65 72 67 65 50 74 72 20 29  >pPrevMergePtr )
1c230 20 2a 70 43 73 72 2d 3e 70 50 72 65 76 4d 65 72   *pCsr->pPrevMer
1c240 67 65 50 74 72 20 3d 20 69 46 50 74 72 3b 0a 20  gePtr = iFPtr;. 
1c250 20 20 20 70 4d 57 2d 3e 61 53 61 76 65 5b 30 5d     pMW->aSave[0]
1c260 2e 62 53 74 6f 72 65 20 3d 20 31 3b 0a 20 20 7d  .bStore = 1;.  }
1c270 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
1c280 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 72  ..static int mer
1c290 67 65 57 6f 72 6b 65 72 57 72 69 74 65 28 0a 20  geWorkerWrite(. 
1c2a0 20 4d 65 72 67 65 57 6f 72 6b 65 72 20 2a 70 4d   MergeWorker *pM
1c2b0 57 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  W,              
1c2c0 20 2f 2a 20 4d 65 72 67 65 20 77 6f 72 6b 65 72   /* Merge worker
1c2d0 20 6f 62 6a 65 63 74 20 74 6f 20 77 72 69 74 65   object to write
1c2e0 20 69 6e 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 65   into */.  int e
1c2f0 54 79 70 65 2c 20 20 20 20 20 20 20 20 20 20 20  Type,           
1c300 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e             /* On
1c310 65 20 6f 66 20 53 4f 52 54 45 44 5f 53 45 50 41  e of SORTED_SEPA
1c320 52 41 54 4f 52 2c 20 57 52 49 54 45 20 6f 72 20  RATOR, WRITE or 
1c330 44 45 4c 45 54 45 20 2a 2f 0a 20 20 76 6f 69 64  DELETE */.  void
1c340 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79   *pKey, int nKey
1c350 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4b  ,           /* K
1c360 65 79 20 76 61 6c 75 65 20 2a 2f 0a 20 20 76 6f  ey value */.  vo
1c370 69 64 20 2a 70 56 61 6c 2c 20 69 6e 74 20 6e 56  id *pVal, int nV
1c380 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  al,           /*
1c390 20 56 61 6c 75 65 20 76 61 6c 75 65 20 2a 2f 0a   Value value */.
1c3a0 20 20 69 6e 74 20 69 50 74 72 20 20 20 20 20 20    int iPtr      
1c3b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c3c0 20 20 2f 2a 20 41 62 73 6f 6c 75 74 65 20 76 61    /* Absolute va
1c3d0 6c 75 65 20 6f 66 20 70 61 67 65 20 70 6f 69 6e  lue of page poin
1c3e0 74 65 72 2c 20 6f 72 20 30 20 2a 2f 0a 29 7b 0a  ter, or 0 */.){.
1c3f0 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f    int rc = LSM_O
1c400 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  K;              
1c410 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
1c420 20 2a 2f 0a 20 20 4d 65 72 67 65 20 2a 70 4d 65   */.  Merge *pMe
1c430 72 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  rge;            
1c440 20 20 20 20 20 20 2f 2a 20 50 65 72 73 69 73 74        /* Persist
1c450 65 6e 74 20 70 61 72 74 20 6f 66 20 6c 65 76 65  ent part of leve
1c460 6c 20 6d 65 72 67 65 20 73 74 61 74 65 20 2a 2f  l merge state */
1c470 0a 20 20 69 6e 74 20 6e 48 64 72 3b 20 20 20 20  .  int nHdr;    
1c480 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c490 20 20 20 2f 2a 20 53 70 61 63 65 20 72 65 71 75     /* Space requ
1c4a0 69 72 65 64 20 66 6f 72 20 74 68 69 73 20 72 65  ired for this re
1c4b0 63 6f 72 64 20 68 65 61 64 65 72 20 2a 2f 0a 20  cord header */. 
1c4c0 20 50 61 67 65 20 2a 70 50 67 3b 20 20 20 20 20   Page *pPg;     
1c4d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c4e0 20 2f 2a 20 50 61 67 65 20 74 6f 20 77 72 69 74   /* Page to writ
1c4f0 65 20 74 6f 20 2a 2f 0a 20 20 75 38 20 2a 61 44  e to */.  u8 *aD
1c500 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20  ata;            
1c510 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
1c520 61 20 62 75 66 66 65 72 20 66 6f 72 20 70 61 67  a buffer for pag
1c530 65 20 70 57 72 69 74 65 72 2d 3e 70 50 61 67 65  e pWriter->pPage
1c540 20 2a 2f 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b   */.  int nData;
1c550 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c560 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
1c570 20 62 75 66 66 65 72 20 61 44 61 74 61 5b 5d 20   buffer aData[] 
1c580 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e  in bytes */.  in
1c590 74 20 6e 52 65 63 3b 20 20 20 20 20 20 20 20 20  t nRec;         
1c5a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1c5b0 20 4e 75 6d 62 65 72 20 6f 66 20 72 65 63 6f 72   Number of recor
1c5c0 64 73 20 6f 6e 20 70 61 67 65 20 70 50 67 20 2a  ds on page pPg *
1c5d0 2f 0a 20 20 69 6e 74 20 69 46 50 74 72 3b 20 20  /.  int iFPtr;  
1c5e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c5f0 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f 66 20      /* Value of 
1c600 70 6f 69 6e 74 65 72 20 69 6e 20 66 6f 6f 74 65  pointer in foote
1c610 72 20 6f 66 20 70 50 67 20 2a 2f 0a 20 20 69 6e  r of pPg */.  in
1c620 74 20 69 52 50 74 72 20 3d 20 30 3b 20 20 20 20  t iRPtr = 0;    
1c630 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1c640 20 56 61 6c 75 65 20 6f 66 20 70 6f 69 6e 74 65   Value of pointe
1c650 72 20 77 72 69 74 74 65 6e 20 69 6e 74 6f 20 72  r written into r
1c660 65 63 6f 72 64 20 2a 2f 0a 20 20 69 6e 74 20 69  ecord */.  int i
1c670 4f 66 66 3b 20 20 20 20 20 20 20 20 20 20 20 20  Off;            
1c680 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
1c690 72 72 65 6e 74 20 77 72 69 74 65 20 6f 66 66 73  rrent write offs
1c6a0 65 74 20 77 69 74 68 69 6e 20 70 61 67 65 20 70  et within page p
1c6b0 50 67 20 2a 2f 0a 20 20 53 65 67 6d 65 6e 74 20  Pg */.  Segment 
1c6c0 2a 70 53 65 67 3b 20 20 20 20 20 20 20 20 20 20  *pSeg;          
1c6d0 20 20 20 20 20 20 20 20 2f 2a 20 53 65 67 6d 65          /* Segme
1c6e0 6e 74 20 62 65 69 6e 67 20 77 72 69 74 74 65 6e  nt being written
1c6f0 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73 20   */.  int flags 
1c700 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
1c710 20 20 20 20 20 20 2f 2a 20 49 66 20 21 3d 20 30        /* If != 0
1c720 2c 20 66 6c 61 67 73 20 76 61 6c 75 65 20 66 6f  , flags value fo
1c730 72 20 70 61 67 65 20 66 6f 6f 74 65 72 20 2a 2f  r page footer */
1c740 0a 20 20 69 6e 74 20 62 46 69 72 73 74 20 3d 20  .  int bFirst = 
1c750 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
1c760 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 66     /* True for f
1c770 69 72 73 74 20 6b 65 79 20 6f 66 20 6f 75 74 70  irst key of outp
1c780 75 74 20 72 75 6e 20 2a 2f 0a 0a 20 20 70 4d 65  ut run */..  pMe
1c790 72 67 65 20 3d 20 70 4d 57 2d 3e 70 4c 65 76 65  rge = pMW->pLeve
1c7a0 6c 2d 3e 70 4d 65 72 67 65 3b 20 20 20 20 0a 20  l->pMerge;    . 
1c7b0 20 70 53 65 67 20 3d 20 26 70 4d 57 2d 3e 70 4c   pSeg = &pMW->pL
1c7c0 65 76 65 6c 2d 3e 6c 68 73 3b 0a 0a 20 20 69 66  evel->lhs;..  if
1c7d0 28 20 70 53 65 67 2d 3e 69 46 69 72 73 74 3d 3d  ( pSeg->iFirst==
1c7e0 30 20 26 26 20 70 4d 57 2d 3e 70 50 61 67 65 3d  0 && pMW->pPage=
1c7f0 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 6d  =0 ){.    rc = m
1c800 65 72 67 65 57 6f 72 6b 65 72 46 69 72 73 74 50  ergeWorkerFirstP
1c810 61 67 65 28 70 4d 57 29 3b 0a 20 20 20 20 62 46  age(pMW);.    bF
1c820 69 72 73 74 20 3d 20 31 3b 0a 20 20 7d 0a 20 20  irst = 1;.  }.  
1c830 70 50 67 20 3d 20 70 4d 57 2d 3e 70 50 61 67 65  pPg = pMW->pPage
1c840 3b 0a 20 20 69 66 28 20 70 50 67 20 29 7b 0a 20  ;.  if( pPg ){. 
1c850 20 20 20 61 44 61 74 61 20 3d 20 66 73 50 61 67     aData = fsPag
1c860 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44 61 74  eData(pPg, &nDat
1c870 61 29 3b 0a 20 20 20 20 6e 52 65 63 20 3d 20 70  a);.    nRec = p
1c880 61 67 65 47 65 74 4e 52 65 63 28 61 44 61 74 61  ageGetNRec(aData
1c890 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 69 46  , nData);.    iF
1c8a0 50 74 72 20 3d 20 70 61 67 65 47 65 74 50 74 72  Ptr = pageGetPtr
1c8b0 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a  (aData, nData);.
1c8c0 20 20 20 20 69 52 50 74 72 20 3d 20 69 50 74 72      iRPtr = iPtr
1c8d0 20 2d 20 69 46 50 74 72 3b 0a 20 20 7d 0a 20 20   - iFPtr;.  }.  
1c8e0 20 20 20 0a 20 20 2f 2a 20 46 69 67 75 72 65 20     .  /* Figure 
1c8f0 6f 75 74 20 68 6f 77 20 6d 75 63 68 20 73 70 61  out how much spa
1c900 63 65 20 69 73 20 72 65 71 75 69 72 65 64 20 62  ce is required b
1c910 79 20 74 68 65 20 6e 65 77 20 72 65 63 6f 72 64  y the new record
1c920 2e 20 54 68 65 20 73 70 61 63 65 0a 20 20 2a 2a  . The space.  **
1c930 20 72 65 71 75 69 72 65 64 20 69 73 20 64 69 76   required is div
1c940 69 64 65 64 20 69 6e 74 6f 20 74 77 6f 20 73 65  ided into two se
1c950 63 74 69 6f 6e 73 3a 20 74 68 65 20 68 65 61 64  ctions: the head
1c960 65 72 20 61 6e 64 20 74 68 65 20 62 6f 64 79 2e  er and the body.
1c970 20 54 68 65 0a 20 20 2a 2a 20 68 65 61 64 65 72   The.  ** header
1c980 20 63 6f 6e 73 69 73 74 73 20 6f 66 20 74 68 65   consists of the
1c990 20 69 6e 74 69 61 6c 20 76 61 72 69 6e 74 20 66   intial varint f
1c9a0 69 65 6c 64 73 2e 20 54 68 65 20 62 6f 64 79 20  ields. The body 
1c9b0 61 72 65 20 74 68 65 20 62 6c 6f 62 73 20 0a 20  are the blobs . 
1c9c0 20 2a 2a 20 6f 66 20 64 61 74 61 20 74 68 61 74   ** of data that
1c9d0 20 63 6f 72 72 65 73 70 6f 6e 64 20 74 6f 20 74   correspond to t
1c9e0 68 65 20 6b 65 79 20 61 6e 64 20 76 61 6c 75 65  he key and value
1c9f0 20 64 61 74 61 2e 20 54 68 65 20 65 6e 74 69 72   data. The entir
1ca00 65 20 68 65 61 64 65 72 20 0a 20 20 2a 2a 20 6d  e header .  ** m
1ca10 75 73 74 20 62 65 20 73 74 6f 72 65 64 20 6f 6e  ust be stored on
1ca20 20 74 68 65 20 70 61 67 65 2e 20 54 68 65 20 62   the page. The b
1ca30 6f 64 79 20 6d 61 79 20 6f 76 65 72 66 6c 6f 77  ody may overflow
1ca40 20 6f 6e 74 6f 20 74 68 65 20 6e 65 78 74 20 61   onto the next a
1ca50 6e 64 0a 20 20 2a 2a 20 73 75 62 73 65 71 75 65  nd.  ** subseque
1ca60 6e 74 20 70 61 67 65 73 2e 0a 20 20 2a 2a 0a 20  nt pages..  **. 
1ca70 20 2a 2a 20 54 68 65 20 68 65 61 64 65 72 20 73   ** The header s
1ca80 70 61 63 65 20 69 73 3a 0a 20 20 2a 2a 0a 20 20  pace is:.  **.  
1ca90 2a 2a 20 20 20 20 20 31 29 20 72 65 63 6f 72 64  **     1) record
1caa0 20 74 79 70 65 20 2d 20 31 20 62 79 74 65 2e 0a   type - 1 byte..
1cab0 20 20 2a 2a 20 20 20 20 20 32 29 20 50 61 67 65    **     2) Page
1cac0 2d 70 6f 69 6e 74 65 72 2d 6f 66 66 73 65 74 20  -pointer-offset 
1cad0 2d 20 31 20 76 61 72 69 6e 74 0a 20 20 2a 2a 20  - 1 varint.  ** 
1cae0 20 20 20 20 33 29 20 4b 65 79 20 73 69 7a 65 20      3) Key size 
1caf0 2d 20 31 20 76 61 72 69 6e 74 0a 20 20 2a 2a 20  - 1 varint.  ** 
1cb00 20 20 20 20 34 29 20 56 61 6c 75 65 20 73 69 7a      4) Value siz
1cb10 65 20 2d 20 31 20 76 61 72 69 6e 74 20 28 6f 6e  e - 1 varint (on
1cb20 6c 79 20 69 66 20 4c 53 4d 5f 49 4e 53 45 52 54  ly if LSM_INSERT
1cb30 20 66 6c 61 67 20 69 73 20 73 65 74 29 0a 20 20   flag is set).  
1cb40 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d  */.  if( rc==LSM
1cb50 5f 4f 4b 20 29 7b 0a 20 20 20 20 6e 48 64 72 20  _OK ){.    nHdr 
1cb60 3d 20 31 20 2b 20 6c 73 6d 56 61 72 69 6e 74 4c  = 1 + lsmVarintL
1cb70 65 6e 33 32 28 69 52 50 74 72 29 20 2b 20 6c 73  en32(iRPtr) + ls
1cb80 6d 56 61 72 69 6e 74 4c 65 6e 33 32 28 6e 4b 65  mVarintLen32(nKe
1cb90 79 29 3b 0a 20 20 20 20 69 66 28 20 72 74 49 73  y);.    if( rtIs
1cba0 57 72 69 74 65 28 65 54 79 70 65 29 20 29 20 6e  Write(eType) ) n
1cbb0 48 64 72 20 2b 3d 20 6c 73 6d 56 61 72 69 6e 74  Hdr += lsmVarint
1cbc0 4c 65 6e 33 32 28 6e 56 61 6c 29 3b 0a 0a 20 20  Len32(nVal);..  
1cbd0 20 20 2f 2a 20 49 66 20 74 68 65 20 65 6e 74 69    /* If the enti
1cbe0 72 65 20 68 65 61 64 65 72 20 77 69 6c 6c 20 6e  re header will n
1cbf0 6f 74 20 66 69 74 20 6f 6e 20 70 61 67 65 20 70  ot fit on page p
1cc00 50 67 2c 20 6f 72 20 69 66 20 70 61 67 65 20 70  Pg, or if page p
1cc10 50 67 20 69 73 20 0a 20 20 20 20 2a 2a 20 6d 61  Pg is .    ** ma
1cc20 72 6b 65 64 20 72 65 61 64 2d 6f 6e 6c 79 2c 20  rked read-only, 
1cc30 61 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20 6e  advance to the n
1cc40 65 78 74 20 70 61 67 65 20 6f 66 20 74 68 65 20  ext page of the 
1cc50 6f 75 74 70 75 74 20 72 75 6e 2e 20 2a 2f 0a 20  output run. */. 
1cc60 20 20 20 69 4f 66 66 20 3d 20 70 4d 65 72 67 65     iOff = pMerge
1cc70 2d 3e 69 4f 75 74 70 75 74 4f 66 66 3b 0a 20 20  ->iOutputOff;.  
1cc80 20 20 69 66 28 20 69 4f 66 66 3c 30 20 7c 7c 20    if( iOff<0 || 
1cc90 70 50 67 3d 3d 30 20 7c 7c 20 69 4f 66 66 2b 6e  pPg==0 || iOff+n
1cca0 48 64 72 20 3e 20 53 45 47 4d 45 4e 54 5f 45 4f  Hdr > SEGMENT_EO
1ccb0 46 28 6e 44 61 74 61 2c 20 6e 52 65 63 2b 31 29  F(nData, nRec+1)
1ccc0 20 29 7b 0a 20 20 20 20 20 20 69 46 50 74 72 20   ){.      iFPtr 
1ccd0 3d 20 2a 70 4d 57 2d 3e 70 43 73 72 2d 3e 70 50  = *pMW->pCsr->pP
1cce0 72 65 76 4d 65 72 67 65 50 74 72 3b 0a 20 20 20  revMergePtr;.   
1ccf0 20 20 20 69 52 50 74 72 20 3d 20 69 50 74 72 20     iRPtr = iPtr 
1cd00 2d 20 69 46 50 74 72 3b 0a 20 20 20 20 20 20 69  - iFPtr;.      i
1cd10 4f 66 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 6e  Off = 0;.      n
1cd20 52 65 63 20 3d 20 30 3b 0a 20 20 20 20 20 20 72  Rec = 0;.      r
1cd30 63 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65 72 4e  c = mergeWorkerN
1cd40 65 78 74 50 61 67 65 28 70 4d 57 2c 20 69 46 50  extPage(pMW, iFP
1cd50 74 72 29 3b 0a 20 20 20 20 20 20 70 50 67 20 3d  tr);.      pPg =
1cd60 20 70 4d 57 2d 3e 70 50 61 67 65 3b 0a 20 20 20   pMW->pPage;.   
1cd70 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20   }.  }..  /* If 
1cd80 74 68 69 73 20 72 65 63 6f 72 64 20 68 65 61 64  this record head
1cd90 65 72 20 77 69 6c 6c 20 62 65 20 74 68 65 20 66  er will be the f
1cda0 69 72 73 74 20 6f 6e 20 74 68 65 20 70 61 67 65  irst on the page
1cdb0 2c 20 61 6e 64 20 74 68 65 20 70 61 67 65 20 69  , and the page i
1cdc0 73 20 0a 20 20 2a 2a 20 6e 6f 74 20 74 68 65 20  s .  ** not the 
1cdd0 76 65 72 79 20 66 69 72 73 74 20 69 6e 20 74 68  very first in th
1cde0 65 20 65 6e 74 69 72 65 20 72 75 6e 2c 20 61 64  e entire run, ad
1cdf0 64 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20  d a copy of the 
1ce00 6b 65 79 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20  key to the.  ** 
1ce10 62 2d 74 72 65 65 20 68 69 65 72 61 72 63 68 79  b-tree hierarchy
1ce20 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d  ..  */.  if( rc=
1ce30 3d 4c 53 4d 5f 4f 4b 20 26 26 20 6e 52 65 63 3d  =LSM_OK && nRec=
1ce40 3d 30 20 26 26 20 62 46 69 72 73 74 3d 3d 30 20  =0 && bFirst==0 
1ce50 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  ){.    assert( p
1ce60 4d 65 72 67 65 2d 3e 6e 53 6b 69 70 3e 3d 30 20  Merge->nSkip>=0 
1ce70 29 3b 0a 0a 20 20 20 20 69 66 28 20 70 4d 65 72  );..    if( pMer
1ce80 67 65 2d 3e 6e 53 6b 69 70 3d 3d 30 20 29 7b 0a  ge->nSkip==0 ){.
1ce90 20 20 20 20 20 20 72 63 20 3d 20 6d 65 72 67 65        rc = merge
1cea0 57 6f 72 6b 65 72 50 75 73 68 48 69 65 72 61 72  WorkerPushHierar
1ceb0 63 68 79 28 70 4d 57 2c 20 72 74 54 6f 70 69 63  chy(pMW, rtTopic
1cec0 28 65 54 79 70 65 29 2c 20 70 4b 65 79 2c 20 6e  (eType), pKey, n
1ced0 4b 65 79 29 3b 0a 20 20 20 20 20 20 61 73 73 65  Key);.      asse
1cee0 72 74 28 20 70 4d 57 2d 3e 61 53 61 76 65 5b 30  rt( pMW->aSave[0
1cef0 5d 2e 62 53 74 6f 72 65 3d 3d 30 20 29 3b 0a 20  ].bStore==0 );. 
1cf00 20 20 20 20 20 70 4d 57 2d 3e 61 53 61 76 65 5b       pMW->aSave[
1cf10 30 5d 2e 62 53 74 6f 72 65 20 3d 20 31 3b 0a 20  0].bStore = 1;. 
1cf20 20 20 20 20 20 70 4d 65 72 67 65 2d 3e 6e 53 6b       pMerge->nSk
1cf30 69 70 20 3d 20 6b 65 79 73 7a 54 6f 53 6b 69 70  ip = keyszToSkip
1cf40 28 70 4d 57 2d 3e 70 44 62 2d 3e 70 46 53 2c 20  (pMW->pDb->pFS, 
1cf50 6e 4b 65 79 29 3b 0a 20 20 20 20 7d 65 6c 73 65  nKey);.    }else
1cf60 7b 0a 20 20 20 20 20 20 70 4d 65 72 67 65 2d 3e  {.      pMerge->
1cf70 6e 53 6b 69 70 2d 2d 3b 0a 20 20 20 20 20 20 66  nSkip--;.      f
1cf80 6c 61 67 73 20 3d 20 50 47 46 54 52 5f 53 4b 49  lags = PGFTR_SKI
1cf90 50 5f 54 48 49 53 5f 46 4c 41 47 3b 0a 20 20 20  P_THIS_FLAG;.   
1cfa0 20 7d 0a 0a 20 20 20 20 69 66 28 20 70 4d 65 72   }..    if( pMer
1cfb0 67 65 2d 3e 6e 53 6b 69 70 20 29 20 66 6c 61 67  ge->nSkip ) flag
1cfc0 73 20 7c 3d 20 50 47 46 54 52 5f 53 4b 49 50 5f  s |= PGFTR_SKIP_
1cfd0 4e 45 58 54 5f 46 4c 41 47 3b 0a 20 20 7d 0a 0a  NEXT_FLAG;.  }..
1cfe0 20 20 2f 2a 20 55 70 64 61 74 65 20 74 68 65 20    /* Update the 
1cff0 6f 75 74 70 75 74 20 73 65 67 6d 65 6e 74 20 2a  output segment *
1d000 2f 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f  /.  if( rc==LSM_
1d010 4f 4b 20 29 7b 0a 20 20 20 20 61 44 61 74 61 20  OK ){.    aData 
1d020 3d 20 66 73 50 61 67 65 44 61 74 61 28 70 50 67  = fsPageData(pPg
1d030 2c 20 26 6e 44 61 74 61 29 3b 0a 0a 20 20 20 20  , &nData);..    
1d040 2f 2a 20 55 70 64 61 74 65 20 74 68 65 20 70 61  /* Update the pa
1d050 67 65 20 66 6f 6f 74 65 72 2e 20 2a 2f 0a 20 20  ge footer. */.  
1d060 20 20 6c 73 6d 50 75 74 55 31 36 28 26 61 44 61    lsmPutU16(&aDa
1d070 74 61 5b 53 45 47 4d 45 4e 54 5f 4e 52 45 43 4f  ta[SEGMENT_NRECO
1d080 52 44 5f 4f 46 46 53 45 54 28 6e 44 61 74 61 29  RD_OFFSET(nData)
1d090 5d 2c 20 6e 52 65 63 2b 31 29 3b 0a 20 20 20 20  ], nRec+1);.    
1d0a0 6c 73 6d 50 75 74 55 31 36 28 26 61 44 61 74 61  lsmPutU16(&aData
1d0b0 5b 53 45 47 4d 45 4e 54 5f 43 45 4c 4c 50 54 52  [SEGMENT_CELLPTR
1d0c0 5f 4f 46 46 53 45 54 28 6e 44 61 74 61 2c 20 6e  _OFFSET(nData, n
1d0d0 52 65 63 29 5d 2c 20 69 4f 66 66 29 3b 0a 20 20  Rec)], iOff);.  
1d0e0 20 20 69 66 28 20 66 6c 61 67 73 20 29 20 6c 73    if( flags ) ls
1d0f0 6d 50 75 74 55 31 36 28 26 61 44 61 74 61 5b 53  mPutU16(&aData[S
1d100 45 47 4d 45 4e 54 5f 46 4c 41 47 53 5f 4f 46 46  EGMENT_FLAGS_OFF
1d110 53 45 54 28 6e 44 61 74 61 29 5d 2c 20 66 6c 61  SET(nData)], fla
1d120 67 73 29 3b 0a 0a 20 20 20 20 2f 2a 20 57 72 69  gs);..    /* Wri
1d130 74 65 20 74 68 65 20 65 6e 74 72 79 20 68 65 61  te the entry hea
1d140 64 65 72 20 69 6e 74 6f 20 74 68 65 20 63 75 72  der into the cur
1d150 72 65 6e 74 20 70 61 67 65 2e 20 2a 2f 0a 20 20  rent page. */.  
1d160 20 20 61 44 61 74 61 5b 69 4f 66 66 2b 2b 5d 20    aData[iOff++] 
1d170 3d 20 65 54 79 70 65 3b 20 20 20 20 20 20 20 20  = eType;        
1d180 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d190 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d1a0 20 20 20 20 20 20 20 2f 2a 20 31 20 2a 2f 0a 20         /* 1 */. 
1d1b0 20 20 20 69 4f 66 66 20 2b 3d 20 6c 73 6d 56 61     iOff += lsmVa
1d1c0 72 69 6e 74 50 75 74 33 32 28 26 61 44 61 74 61  rintPut32(&aData
1d1d0 5b 69 4f 66 66 5d 2c 20 69 52 50 74 72 29 3b 20  [iOff], iRPtr); 
1d1e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d1f0 20 20 20 20 20 20 20 20 2f 2a 20 32 20 2a 2f 0a          /* 2 */.
1d200 20 20 20 20 69 4f 66 66 20 2b 3d 20 6c 73 6d 56      iOff += lsmV
1d210 61 72 69 6e 74 50 75 74 33 32 28 26 61 44 61 74  arintPut32(&aDat
1d220 61 5b 69 4f 66 66 5d 2c 20 6e 4b 65 79 29 3b 20  a[iOff], nKey); 
1d230 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d240 20 20 20 20 20 20 20 20 20 2f 2a 20 33 20 2a 2f           /* 3 */
1d250 0a 20 20 20 20 69 66 28 20 72 74 49 73 57 72 69  .    if( rtIsWri
1d260 74 65 28 65 54 79 70 65 29 20 29 20 69 4f 66 66  te(eType) ) iOff
1d270 20 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 50 75 74   += lsmVarintPut
1d280 33 32 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c  32(&aData[iOff],
1d290 20 6e 56 61 6c 29 3b 20 20 20 2f 2a 20 34 20 2a   nVal);   /* 4 *
1d2a0 2f 0a 20 20 20 20 70 4d 65 72 67 65 2d 3e 69 4f  /.    pMerge->iO
1d2b0 75 74 70 75 74 4f 66 66 20 3d 20 69 4f 66 66 3b  utputOff = iOff;
1d2c0 0a 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74  ..    /* Write t
1d2d0 68 65 20 6b 65 79 20 61 6e 64 20 64 61 74 61 20  he key and data 
1d2e0 69 6e 74 6f 20 74 68 65 20 73 65 67 6d 65 6e 74  into the segment
1d2f0 2e 20 2a 2f 0a 20 20 20 20 61 73 73 65 72 74 28  . */.    assert(
1d300 20 69 46 50 74 72 3d 3d 70 61 67 65 47 65 74 50   iFPtr==pageGetP
1d310 74 72 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29  tr(aData, nData)
1d320 20 29 3b 0a 20 20 20 20 72 63 20 3d 20 6d 65 72   );.    rc = mer
1d330 67 65 57 6f 72 6b 65 72 44 61 74 61 28 70 4d 57  geWorkerData(pMW
1d340 2c 20 30 2c 20 69 46 50 74 72 2b 69 52 50 74 72  , 0, iFPtr+iRPtr
1d350 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 20  , pKey, nKey);. 
1d360 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
1d370 4b 20 26 26 20 72 74 49 73 57 72 69 74 65 28 65  K && rtIsWrite(e
1d380 54 79 70 65 29 20 29 7b 0a 20 20 20 20 20 20 69  Type) ){.      i
1d390 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b  f( rc==LSM_OK ){
1d3a0 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 6d 65  .        rc = me
1d3b0 72 67 65 57 6f 72 6b 65 72 44 61 74 61 28 70 4d  rgeWorkerData(pM
1d3c0 57 2c 20 30 2c 20 69 46 50 74 72 2b 69 52 50 74  W, 0, iFPtr+iRPt
1d3d0 72 2c 20 70 56 61 6c 2c 20 6e 56 61 6c 29 3b 0a  r, pVal, nVal);.
1d3e0 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
1d3f0 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
1d400 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61  }.../*.** Free a
1d410 6c 6c 20 72 65 73 6f 75 72 63 65 73 20 61 6c 6c  ll resources all
1d420 6f 63 61 74 65 64 20 62 79 20 6d 65 72 67 65 57  ocated by mergeW
1d430 6f 72 6b 65 72 49 6e 69 74 28 29 2e 0a 2a 2f 0a  orkerInit()..*/.
1d440 73 74 61 74 69 63 20 76 6f 69 64 20 6d 65 72 67  static void merg
1d450 65 57 6f 72 6b 65 72 53 68 75 74 64 6f 77 6e 28  eWorkerShutdown(
1d460 4d 65 72 67 65 57 6f 72 6b 65 72 20 2a 70 4d 57  MergeWorker *pMW
1d470 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 69  , int *pRc){.  i
1d480 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20  nt i;           
1d490 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1d4a0 2a 20 49 74 65 72 61 74 6f 72 20 76 61 72 69 61  * Iterator varia
1d4b0 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20  ble */.  int rc 
1d4c0 3d 20 2a 70 52 63 3b 0a 20 20 4d 75 6c 74 69 43  = *pRc;.  MultiC
1d4d0 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 70 4d  ursor *pCsr = pM
1d4e0 57 2d 3e 70 43 73 72 3b 0a 0a 20 20 2f 2a 20 55  W->pCsr;..  /* U
1d4f0 6e 6c 65 73 73 20 74 68 65 20 6d 65 72 67 65 20  nless the merge 
1d500 68 61 73 20 66 69 6e 69 73 68 65 64 2c 20 73 61  has finished, sa
1d510 76 65 20 74 68 65 20 63 75 72 73 6f 72 20 70 6f  ve the cursor po
1d520 73 69 74 69 6f 6e 20 69 6e 20 74 68 65 0a 20 20  sition in the.  
1d530 2a 2a 20 4d 65 72 67 65 2e 61 49 6e 70 75 74 5b  ** Merge.aInput[
1d540 5d 20 61 72 72 61 79 2e 20 53 65 65 20 66 75 6e  ] array. See fun
1d550 63 74 69 6f 6e 20 6d 65 72 67 65 57 6f 72 6b 65  ction mergeWorke
1d560 72 49 6e 69 74 28 29 20 66 6f 72 20 74 68 65 20  rInit() for the 
1d570 0a 20 20 2a 2a 20 63 6f 64 65 20 74 6f 20 72 65  .  ** code to re
1d580 73 74 6f 72 65 20 61 20 63 75 72 73 6f 72 20 70  store a cursor p
1d590 6f 73 69 74 69 6f 6e 20 62 61 73 65 64 20 6f 6e  osition based on
1d5a0 20 61 49 6e 70 75 74 5b 5d 2e 20 20 2a 2f 0a 20   aInput[].  */. 
1d5b0 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
1d5c0 26 26 20 70 43 73 72 20 26 26 20 6c 73 6d 4d 43  && pCsr && lsmMC
1d5d0 75 72 73 6f 72 56 61 6c 69 64 28 70 43 73 72 29  ursorValid(pCsr)
1d5e0 20 29 7b 0a 20 20 20 20 4d 65 72 67 65 20 2a 70   ){.    Merge *p
1d5f0 4d 65 72 67 65 20 3d 20 70 4d 57 2d 3e 70 4c 65  Merge = pMW->pLe
1d600 76 65 6c 2d 3e 70 4d 65 72 67 65 3b 0a 20 20 20  vel->pMerge;.   
1d610 20 69 6e 74 20 62 42 74 72 65 65 20 3d 20 28 70   int bBtree = (p
1d620 43 73 72 2d 3e 70 42 74 43 73 72 21 3d 30 29 3b  Csr->pBtCsr!=0);
1d630 0a 20 20 20 20 69 6e 74 20 69 50 74 72 3b 0a 0a  .    int iPtr;..
1d640 20 20 20 20 2f 2a 20 70 4d 65 72 67 65 2d 3e 6e      /* pMerge->n
1d650 49 6e 70 75 74 3d 3d 30 20 69 6e 64 69 63 61 74  Input==0 indicat
1d660 65 73 20 74 68 61 74 20 74 68 69 73 20 69 73 20  es that this is 
1d670 61 20 46 6c 75 73 68 54 72 65 65 28 29 20 6f 70  a FlushTree() op
1d680 65 72 61 74 69 6f 6e 2e 20 2a 2f 0a 20 20 20 20  eration. */.    
1d690 61 73 73 65 72 74 28 20 70 4d 65 72 67 65 2d 3e  assert( pMerge->
1d6a0 6e 49 6e 70 75 74 3d 3d 30 20 7c 7c 20 70 4d 57  nInput==0 || pMW
1d6b0 2d 3e 70 4c 65 76 65 6c 2d 3e 6e 52 69 67 68 74  ->pLevel->nRight
1d6c0 3e 30 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  >0 );.    assert
1d6d0 28 20 70 4d 65 72 67 65 2d 3e 6e 49 6e 70 75 74  ( pMerge->nInput
1d6e0 3d 3d 30 20 7c 7c 20 70 4d 65 72 67 65 2d 3e 6e  ==0 || pMerge->n
1d6f0 49 6e 70 75 74 3d 3d 28 70 43 73 72 2d 3e 6e 50  Input==(pCsr->nP
1d700 74 72 2b 62 42 74 72 65 65 29 20 29 3b 0a 0a 20  tr+bBtree) );.. 
1d710 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 28 70     for(i=0; i<(p
1d720 4d 65 72 67 65 2d 3e 6e 49 6e 70 75 74 2d 62 42  Merge->nInput-bB
1d730 74 72 65 65 29 3b 20 69 2b 2b 29 7b 0a 20 20 20  tree); i++){.   
1d740 20 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70     SegmentPtr *p
1d750 50 74 72 20 3d 20 26 70 43 73 72 2d 3e 61 50 74  Ptr = &pCsr->aPt
1d760 72 5b 69 5d 3b 0a 20 20 20 20 20 20 69 66 28 20  r[i];.      if( 
1d770 70 50 74 72 2d 3e 70 50 67 20 29 7b 0a 20 20 20  pPtr->pPg ){.   
1d780 20 20 20 20 20 70 4d 65 72 67 65 2d 3e 61 49 6e       pMerge->aIn
1d790 70 75 74 5b 69 5d 2e 69 50 67 20 3d 20 6c 73 6d  put[i].iPg = lsm
1d7a0 46 73 50 61 67 65 4e 75 6d 62 65 72 28 70 50 74  FsPageNumber(pPt
1d7b0 72 2d 3e 70 50 67 29 3b 0a 20 20 20 20 20 20 20  r->pPg);.       
1d7c0 20 70 4d 65 72 67 65 2d 3e 61 49 6e 70 75 74 5b   pMerge->aInput[
1d7d0 69 5d 2e 69 43 65 6c 6c 20 3d 20 70 50 74 72 2d  i].iCell = pPtr-
1d7e0 3e 69 43 65 6c 6c 3b 0a 20 20 20 20 20 20 7d 65  >iCell;.      }e
1d7f0 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70 4d 65  lse{.        pMe
1d800 72 67 65 2d 3e 61 49 6e 70 75 74 5b 69 5d 2e 69  rge->aInput[i].i
1d810 50 67 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  Pg = 0;.        
1d820 70 4d 65 72 67 65 2d 3e 61 49 6e 70 75 74 5b 69  pMerge->aInput[i
1d830 5d 2e 69 43 65 6c 6c 20 3d 20 30 3b 0a 20 20 20  ].iCell = 0;.   
1d840 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
1d850 66 28 20 62 42 74 72 65 65 20 26 26 20 70 4d 65  f( bBtree && pMe
1d860 72 67 65 2d 3e 6e 49 6e 70 75 74 20 29 7b 0a 20  rge->nInput ){. 
1d870 20 20 20 20 20 61 73 73 65 72 74 28 20 69 3d 3d       assert( i==
1d880 70 43 73 72 2d 3e 6e 50 74 72 20 29 3b 0a 20 20  pCsr->nPtr );.  
1d890 20 20 20 20 62 74 72 65 65 43 75 72 73 6f 72 50      btreeCursorP
1d8a0 6f 73 69 74 69 6f 6e 28 70 43 73 72 2d 3e 70 42  osition(pCsr->pB
1d8b0 74 43 73 72 2c 20 26 70 4d 65 72 67 65 2d 3e 61  tCsr, &pMerge->a
1d8c0 49 6e 70 75 74 5b 69 5d 29 3b 0a 20 20 20 20 7d  Input[i]);.    }
1d8d0 0a 0a 20 20 20 20 2f 2a 20 53 74 6f 72 65 20 74  ..    /* Store t
1d8e0 68 65 20 6c 6f 63 61 74 69 6f 6e 20 6f 66 20 74  he location of t
1d8f0 68 65 20 73 70 6c 69 74 2d 6b 65 79 20 2a 2f 0a  he split-key */.
1d900 20 20 20 20 69 50 74 72 20 3d 20 70 43 73 72 2d      iPtr = pCsr-
1d910 3e 61 54 72 65 65 5b 31 5d 20 2d 20 43 55 52 53  >aTree[1] - CURS
1d920 4f 52 5f 44 41 54 41 5f 53 45 47 4d 45 4e 54 3b  OR_DATA_SEGMENT;
1d930 0a 20 20 20 20 69 66 28 20 69 50 74 72 3c 70 43  .    if( iPtr<pC
1d940 73 72 2d 3e 6e 50 74 72 20 29 7b 0a 20 20 20 20  sr->nPtr ){.    
1d950 20 20 70 4d 65 72 67 65 2d 3e 73 70 6c 69 74 6b    pMerge->splitk
1d960 65 79 20 3d 20 70 4d 65 72 67 65 2d 3e 61 49 6e  ey = pMerge->aIn
1d970 70 75 74 5b 69 50 74 72 5d 3b 0a 20 20 20 20 7d  put[iPtr];.    }
1d980 65 6c 73 65 7b 0a 20 20 20 20 20 20 62 74 72 65  else{.      btre
1d990 65 43 75 72 73 6f 72 53 70 6c 69 74 6b 65 79 28  eCursorSplitkey(
1d9a0 70 43 73 72 2d 3e 70 42 74 43 73 72 2c 20 26 70  pCsr->pBtCsr, &p
1d9b0 4d 65 72 67 65 2d 3e 73 70 6c 69 74 6b 65 79 29  Merge->splitkey)
1d9c0 3b 0a 20 20 20 20 7d 0a 20 20 20 20 0a 20 20 20  ;.    }.    .   
1d9d0 20 70 4d 65 72 67 65 2d 3e 69 4f 75 74 70 75 74   pMerge->iOutput
1d9e0 4f 66 66 20 3d 20 2d 31 3b 0a 20 20 7d 0a 0a 20  Off = -1;.  }.. 
1d9f0 20 6c 73 6d 4d 43 75 72 73 6f 72 43 6c 6f 73 65   lsmMCursorClose
1da00 28 70 43 73 72 2c 20 30 29 3b 0a 0a 20 20 2f 2a  (pCsr, 0);..  /*
1da10 20 50 65 72 73 69 73 74 20 61 6e 64 20 72 65 6c   Persist and rel
1da20 65 61 73 65 20 74 68 65 20 6f 75 74 70 75 74 20  ease the output 
1da30 70 61 67 65 2e 20 2a 2f 0a 20 20 69 66 28 20 72  page. */.  if( r
1da40 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 20 72 63 20 3d  c==LSM_OK ) rc =
1da50 20 6d 65 72 67 65 57 6f 72 6b 65 72 50 65 72 73   mergeWorkerPers
1da60 69 73 74 41 6e 64 52 65 6c 65 61 73 65 28 70 4d  istAndRelease(pM
1da70 57 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53  W);.  if( rc==LS
1da80 4d 5f 4f 4b 20 29 20 72 63 20 3d 20 6d 65 72 67  M_OK ) rc = merg
1da90 65 57 6f 72 6b 65 72 42 74 72 65 65 49 6e 64 69  eWorkerBtreeIndi
1daa0 72 65 63 74 28 70 4d 57 29 3b 0a 20 20 69 66 28  rect(pMW);.  if(
1dab0 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 20 72 63   rc==LSM_OK ) rc
1dac0 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65 72 46 69   = mergeWorkerFi
1dad0 6e 69 73 68 48 69 65 72 61 72 63 68 79 28 70 4d  nishHierarchy(pM
1dae0 57 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53  W);.  if( rc==LS
1daf0 4d 5f 4f 4b 20 29 20 72 63 20 3d 20 6d 65 72 67  M_OK ) rc = merg
1db00 65 57 6f 72 6b 65 72 41 64 64 50 61 64 64 69 6e  eWorkerAddPaddin
1db10 67 28 70 4d 57 29 3b 0a 20 20 6c 73 6d 46 73 46  g(pMW);.  lsmFsF
1db20 6c 75 73 68 57 61 69 74 69 6e 67 28 70 4d 57 2d  lushWaiting(pMW-
1db30 3e 70 44 62 2d 3e 70 46 53 2c 20 26 72 63 29 3b  >pDb->pFS, &rc);
1db40 0a 20 20 6d 65 72 67 65 57 6f 72 6b 65 72 52 65  .  mergeWorkerRe
1db50 6c 65 61 73 65 41 6c 6c 28 70 4d 57 29 3b 0a 0a  leaseAll(pMW);..
1db60 20 20 6c 73 6d 46 72 65 65 28 70 4d 57 2d 3e 70    lsmFree(pMW->p
1db70 44 62 2d 3e 70 45 6e 76 2c 20 70 4d 57 2d 3e 61  Db->pEnv, pMW->a
1db80 47 6f 62 62 6c 65 29 3b 0a 20 20 70 4d 57 2d 3e  Gobble);.  pMW->
1db90 61 47 6f 62 62 6c 65 20 3d 20 30 3b 0a 20 20 70  aGobble = 0;.  p
1dba0 4d 57 2d 3e 70 43 73 72 20 3d 20 30 3b 0a 0a 20  MW->pCsr = 0;.. 
1dbb0 20 2a 70 52 63 20 3d 20 72 63 3b 0a 7d 0a 0a 2f   *pRc = rc;.}../
1dbc0 2a 0a 2a 2a 20 54 68 65 20 63 75 72 73 6f 72 20  *.** The cursor 
1dbd0 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69  passed as the fi
1dbe0 72 73 74 20 61 72 67 75 6d 65 6e 74 20 69 73 20  rst argument is 
1dbf0 62 65 69 6e 67 20 75 73 65 64 20 61 73 20 74 68  being used as th
1dc00 65 20 69 6e 70 75 74 20 66 6f 72 0a 2a 2a 20 61  e input for.** a
1dc10 20 6d 65 72 67 65 20 6f 70 65 72 61 74 69 6f 6e   merge operation
1dc20 2e 20 57 68 65 6e 20 74 68 69 73 20 66 75 6e 63  . When this func
1dc30 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2c 20  tion is called, 
1dc40 2a 70 69 46 6c 61 67 73 20 63 6f 6e 74 61 69 6e  *piFlags contain
1dc50 73 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73  s the.** databas
1dc60 65 20 65 6e 74 72 79 20 66 6c 61 67 73 20 66 6f  e entry flags fo
1dc70 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 65 6e  r the current en
1dc80 74 72 79 2e 20 54 68 65 20 65 6e 74 72 79 20 61  try. The entry a
1dc90 62 6f 75 74 20 74 6f 20 62 65 20 77 72 69 74 74  bout to be writt
1dca0 65 6e 0a 2a 2a 20 74 6f 20 74 68 65 20 6f 75 74  en.** to the out
1dcb0 70 75 74 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20  put..**.** Note 
1dcc0 74 68 61 74 20 74 68 69 73 20 66 75 6e 63 74 69  that this functi
1dcd0 6f 6e 20 6f 6e 6c 79 20 68 61 73 20 74 6f 20 77  on only has to w
1dce0 6f 72 6b 20 66 6f 72 20 63 75 72 73 6f 72 73 20  ork for cursors 
1dcf0 63 6f 6e 66 69 67 75 72 65 64 20 74 6f 20 0a 2a  configured to .*
1dd00 2a 20 69 74 65 72 61 74 65 20 66 6f 72 77 61 72  * iterate forwar
1dd10 64 73 20 28 6e 6f 74 20 62 61 63 6b 77 61 72 64  ds (not backward
1dd20 73 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  s)..*/.static vo
1dd30 69 64 20 6d 65 72 67 65 52 61 6e 67 65 44 65 6c  id mergeRangeDel
1dd40 65 74 65 73 28 4d 75 6c 74 69 43 75 72 73 6f 72  etes(MultiCursor
1dd50 20 2a 70 43 73 72 2c 20 69 6e 74 20 2a 70 69 56   *pCsr, int *piV
1dd60 61 6c 2c 20 69 6e 74 20 2a 70 69 46 6c 61 67 73  al, int *piFlags
1dd70 29 7b 0a 20 20 69 6e 74 20 66 20 3d 20 2a 70 69  ){.  int f = *pi
1dd80 46 6c 61 67 73 3b 0a 20 20 69 6e 74 20 69 4b 65  Flags;.  int iKe
1dd90 79 20 3d 20 70 43 73 72 2d 3e 61 54 72 65 65 5b  y = pCsr->aTree[
1dda0 31 5d 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20  1];.  int i;..  
1ddb0 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e 66 6c  assert( pCsr->fl
1ddc0 61 67 73 20 26 20 43 55 52 53 4f 52 5f 4e 45 58  ags & CURSOR_NEX
1ddd0 54 5f 4f 4b 20 29 3b 0a 20 20 69 66 28 20 70 43  T_OK );.  if( pC
1dde0 73 72 2d 3e 66 6c 61 67 73 20 26 20 43 55 52 53  sr->flags & CURS
1ddf0 4f 52 5f 49 47 4e 4f 52 45 5f 44 45 4c 45 54 45  OR_IGNORE_DELETE
1de00 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 69   ){.    /* The i
1de10 67 6e 6f 72 65 2d 64 65 6c 65 74 65 20 66 6c 61  gnore-delete fla
1de20 67 20 69 73 20 73 65 74 20 77 68 65 6e 20 74 68  g is set when th
1de30 65 20 6f 75 74 70 75 74 20 6f 66 20 74 68 65 20  e output of the 
1de40 6d 65 72 67 65 20 77 69 6c 6c 20 66 6f 72 6d 0a  merge will form.
1de50 20 20 20 20 2a 2a 20 74 68 65 20 6f 6c 64 65 73      ** the oldes
1de60 74 20 6c 65 76 65 6c 20 69 6e 20 74 68 65 20 64  t level in the d
1de70 61 74 61 62 61 73 65 2e 20 49 6e 20 74 68 69 73  atabase. In this
1de80 20 63 61 73 65 20 74 68 65 72 65 20 69 73 20 6e   case there is n
1de90 6f 20 70 6f 69 6e 74 20 69 6e 0a 20 20 20 20 2a  o point in.    *
1dea0 2a 20 72 65 74 61 69 6e 69 6e 67 20 61 6e 79 20  * retaining any 
1deb0 72 61 6e 67 65 2d 64 65 6c 65 74 65 20 66 6c 61  range-delete fla
1dec0 67 73 2e 20 20 2a 2f 0a 20 20 20 20 61 73 73 65  gs.  */.    asse
1ded0 72 74 28 20 28 66 20 26 20 4c 53 4d 5f 50 4f 49  rt( (f & LSM_POI
1dee0 4e 54 5f 44 45 4c 45 54 45 29 3d 3d 30 20 29 3b  NT_DELETE)==0 );
1def0 0a 20 20 20 20 66 20 26 3d 20 7e 28 4c 53 4d 5f  .    f &= ~(LSM_
1df00 53 54 41 52 54 5f 44 45 4c 45 54 45 7c 4c 53 4d  START_DELETE|LSM
1df10 5f 45 4e 44 5f 44 45 4c 45 54 45 29 3b 0a 20 20  _END_DELETE);.  
1df20 7d 65 6c 73 65 7b 0a 20 20 20 20 66 6f 72 28 69  }else{.    for(i
1df30 3d 30 3b 20 69 3c 28 43 55 52 53 4f 52 5f 44 41  =0; i<(CURSOR_DA
1df40 54 41 5f 53 45 47 4d 45 4e 54 20 2b 20 70 43 73  TA_SEGMENT + pCs
1df50 72 2d 3e 6e 50 74 72 29 3b 20 69 2b 2b 29 7b 0a  r->nPtr); i++){.
1df60 20 20 20 20 20 20 69 66 28 20 69 21 3d 69 4b 65        if( i!=iKe
1df70 79 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74  y ){.        int
1df80 20 65 54 79 70 65 3b 0a 20 20 20 20 20 20 20 20   eType;.        
1df90 76 6f 69 64 20 2a 70 4b 65 79 3b 0a 20 20 20 20  void *pKey;.    
1dfa0 20 20 20 20 69 6e 74 20 6e 4b 65 79 3b 0a 20 20      int nKey;.  
1dfb0 20 20 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20        int res;. 
1dfc0 20 20 20 20 20 20 20 6d 75 6c 74 69 43 75 72 73         multiCurs
1dfd0 6f 72 47 65 74 4b 65 79 28 70 43 73 72 2c 20 69  orGetKey(pCsr, i
1dfe0 2c 20 26 65 54 79 70 65 2c 20 26 70 4b 65 79 2c  , &eType, &pKey,
1dff0 20 26 6e 4b 65 79 29 3b 0a 0a 20 20 20 20 20 20   &nKey);..      
1e000 20 20 69 66 28 20 70 4b 65 79 20 29 7b 0a 20 20    if( pKey ){.  
1e010 20 20 20 20 20 20 20 20 72 65 73 20 3d 20 73 6f          res = so
1e020 72 74 65 64 4b 65 79 43 6f 6d 70 61 72 65 28 70  rtedKeyCompare(p
1e030 43 73 72 2d 3e 70 44 62 2d 3e 78 43 6d 70 2c 20  Csr->pDb->xCmp, 
1e040 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72  .              r
1e050 74 54 6f 70 69 63 28 70 43 73 72 2d 3e 65 54 79  tTopic(pCsr->eTy
1e060 70 65 29 2c 20 70 43 73 72 2d 3e 6b 65 79 2e 70  pe), pCsr->key.p
1e070 44 61 74 61 2c 20 70 43 73 72 2d 3e 6b 65 79 2e  Data, pCsr->key.
1e080 6e 44 61 74 61 2c 0a 20 20 20 20 20 20 20 20 20  nData,.         
1e090 20 20 20 20 20 72 74 54 6f 70 69 63 28 65 54 79       rtTopic(eTy
1e0a0 70 65 29 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 0a  pe), pKey, nKey.
1e0b0 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20            );.   
1e0c0 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 72         assert( r
1e0d0 65 73 3c 3d 30 20 29 3b 0a 20 20 20 20 20 20 20  es<=0 );.       
1e0e0 20 20 20 69 66 28 20 72 65 73 3d 3d 30 20 29 7b     if( res==0 ){
1e0f0 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28  .            if(
1e100 20 28 66 20 26 20 28 4c 53 4d 5f 49 4e 53 45 52   (f & (LSM_INSER
1e110 54 7c 4c 53 4d 5f 50 4f 49 4e 54 5f 44 45 4c 45  T|LSM_POINT_DELE
1e120 54 45 29 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  TE))==0 ){.     
1e130 20 20 20 20 20 20 20 20 20 69 66 28 20 65 54 79           if( eTy
1e140 70 65 20 26 20 4c 53 4d 5f 49 4e 53 45 52 54 20  pe & LSM_INSERT 
1e150 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ){.             
1e160 20 20 20 66 20 7c 3d 20 4c 53 4d 5f 49 4e 53 45     f |= LSM_INSE
1e170 52 54 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  RT;.            
1e180 20 20 20 20 2a 70 69 56 61 6c 20 3d 20 69 3b 0a      *piVal = i;.
1e190 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a                }.
1e1a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c                el
1e1b0 73 65 20 69 66 28 20 65 54 79 70 65 20 26 20 4c  se if( eType & L
1e1c0 53 4d 5f 50 4f 49 4e 54 5f 44 45 4c 45 54 45 20  SM_POINT_DELETE 
1e1d0 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ){.             
1e1e0 20 20 20 66 20 7c 3d 20 4c 53 4d 5f 50 4f 49 4e     f |= LSM_POIN
1e1f0 54 5f 44 45 4c 45 54 45 3b 0a 20 20 20 20 20 20  T_DELETE;.      
1e200 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
1e210 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
1e220 20 20 20 20 66 20 7c 3d 20 28 65 54 79 70 65 20      f |= (eType 
1e230 26 20 28 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45 54  & (LSM_END_DELET
1e240 45 7c 4c 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45  E|LSM_START_DELE
1e250 54 45 29 29 3b 0a 20 20 20 20 20 20 20 20 20 20  TE));.          
1e260 7d 0a 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  }..          if(
1e270 20 69 3e 69 4b 65 79 20 26 26 20 28 65 54 79 70   i>iKey && (eTyp
1e280 65 20 26 20 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45  e & LSM_END_DELE
1e290 54 45 29 20 26 26 20 72 65 73 3c 30 20 29 7b 0a  TE) && res<0 ){.
1e2a0 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20              if( 
1e2b0 66 20 26 20 28 4c 53 4d 5f 49 4e 53 45 52 54 7c  f & (LSM_INSERT|
1e2c0 4c 53 4d 5f 50 4f 49 4e 54 5f 44 45 4c 45 54 45  LSM_POINT_DELETE
1e2d0 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  ) ){.           
1e2e0 20 20 20 66 20 7c 3d 20 28 4c 53 4d 5f 45 4e 44     f |= (LSM_END
1e2f0 5f 44 45 4c 45 54 45 7c 4c 53 4d 5f 53 54 41 52  _DELETE|LSM_STAR
1e300 54 5f 44 45 4c 45 54 45 29 3b 0a 20 20 20 20 20  T_DELETE);.     
1e310 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20         }else{.  
1e320 20 20 20 20 20 20 20 20 20 20 20 20 66 20 3d 20              f = 
1e330 30 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d  0;.            }
1e340 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65  .            bre
1e350 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  ak;.          }.
1e360 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
1e370 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 61 73 73  }.    }..    ass
1e380 65 72 74 28 20 28 66 20 26 20 4c 53 4d 5f 49 4e  ert( (f & LSM_IN
1e390 53 45 52 54 29 3d 3d 30 20 7c 7c 20 28 66 20 26  SERT)==0 || (f &
1e3a0 20 4c 53 4d 5f 50 4f 49 4e 54 5f 44 45 4c 45 54   LSM_POINT_DELET
1e3b0 45 29 3d 3d 30 20 29 3b 0a 20 20 20 20 69 66 28  E)==0 );.    if(
1e3c0 20 28 66 20 26 20 4c 53 4d 5f 53 54 41 52 54 5f   (f & LSM_START_
1e3d0 44 45 4c 45 54 45 29 20 0a 20 20 20 20 20 26 26  DELETE) .     &&
1e3e0 20 28 66 20 26 20 4c 53 4d 5f 45 4e 44 5f 44 45   (f & LSM_END_DE
1e3f0 4c 45 54 45 29 20 0a 20 20 20 20 20 26 26 20 28  LETE) .     && (
1e400 66 20 26 20 4c 53 4d 5f 50 4f 49 4e 54 5f 44 45  f & LSM_POINT_DE
1e410 4c 45 54 45 20 29 0a 20 20 20 20 29 7b 0a 20 20  LETE ).    ){.  
1e420 20 20 20 20 66 20 3d 20 30 3b 0a 20 20 20 20 7d      f = 0;.    }
1e430 0a 20 20 7d 0a 0a 20 20 2a 70 69 46 6c 61 67 73  .  }..  *piFlags
1e440 20 3d 20 66 3b 0a 7d 0a 0a 73 74 61 74 69 63 20   = f;.}..static 
1e450 69 6e 74 20 6d 65 72 67 65 57 6f 72 6b 65 72 53  int mergeWorkerS
1e460 74 65 70 28 4d 65 72 67 65 57 6f 72 6b 65 72 20  tep(MergeWorker 
1e470 2a 70 4d 57 29 7b 0a 20 20 6c 73 6d 5f 64 62 20  *pMW){.  lsm_db 
1e480 2a 70 44 62 20 3d 20 70 4d 57 2d 3e 70 44 62 3b  *pDb = pMW->pDb;
1e490 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
1e4a0 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 4d  se handle */.  M
1e4b0 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72  ultiCursor *pCsr
1e4c0 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
1e4d0 43 75 72 73 6f 72 20 74 6f 20 72 65 61 64 20 69  Cursor to read i
1e4e0 6e 70 75 74 20 64 61 74 61 20 66 72 6f 6d 20 2a  nput data from *
1e4f0 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d  /.  int rc = LSM
1e500 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
1e510 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
1e520 20 2a 2f 0a 20 20 69 6e 74 20 65 54 79 70 65 3b   */.  int eType;
1e530 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e540 20 20 20 20 2f 2a 20 53 4f 52 54 45 44 5f 53 45      /* SORTED_SE
1e550 50 41 52 41 54 4f 52 2c 20 57 52 49 54 45 20 6f  PARATOR, WRITE o
1e560 72 20 44 45 4c 45 54 45 20 2a 2f 0a 20 20 76 6f  r DELETE */.  vo
1e570 69 64 20 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b  id *pKey; int nK
1e580 65 79 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 4b  ey;         /* K
1e590 65 79 20 2a 2f 0a 20 20 50 67 6e 6f 20 69 50 74  ey */.  Pgno iPt
1e5a0 72 3b 0a 20 20 69 6e 74 20 69 56 61 6c 3b 0a 0a  r;.  int iVal;..
1e5b0 20 20 70 43 73 72 20 3d 20 70 4d 57 2d 3e 70 43    pCsr = pMW->pC
1e5c0 73 72 3b 0a 0a 20 20 2f 2a 20 50 75 6c 6c 20 74  sr;..  /* Pull t
1e5d0 68 65 20 6e 65 78 74 20 72 65 63 6f 72 64 20 6f  he next record o
1e5e0 75 74 20 6f 66 20 74 68 65 20 73 6f 75 72 63 65  ut of the source
1e5f0 20 63 75 72 73 6f 72 2e 20 2a 2f 0a 20 20 6c 73   cursor. */.  ls
1e600 6d 4d 43 75 72 73 6f 72 4b 65 79 28 70 43 73 72  mMCursorKey(pCsr
1e610 2c 20 26 70 4b 65 79 2c 20 26 6e 4b 65 79 29 3b  , &pKey, &nKey);
1e620 0a 20 20 65 54 79 70 65 20 3d 20 70 43 73 72 2d  .  eType = pCsr-
1e630 3e 65 54 79 70 65 3b 0a 0a 20 20 2f 2a 20 46 69  >eType;..  /* Fi
1e640 67 75 72 65 20 6f 75 74 20 69 66 20 74 68 65 20  gure out if the 
1e650 6f 75 74 70 75 74 20 72 65 63 6f 72 64 20 6d 61  output record ma
1e660 79 20 68 61 76 65 20 61 20 64 69 66 66 65 72 65  y have a differe
1e670 6e 74 20 70 6f 69 6e 74 65 72 20 76 61 6c 75 65  nt pointer value
1e680 0a 20 20 2a 2a 20 74 68 61 6e 20 74 68 65 20 70  .  ** than the p
1e690 72 65 76 69 6f 75 73 2e 20 54 68 69 73 20 69 73  revious. This is
1e6a0 20 74 68 65 20 63 61 73 65 20 69 66 20 74 68 65   the case if the
1e6b0 20 63 75 72 72 65 6e 74 20 6b 65 79 20 69 73 20   current key is 
1e6c0 69 64 65 6e 74 69 63 61 6c 20 74 6f 0a 20 20 2a  identical to.  *
1e6d0 2a 20 61 20 6b 65 79 20 74 68 61 74 20 61 70 70  * a key that app
1e6e0 65 61 72 73 20 69 6e 20 74 68 65 20 6c 6f 77 65  ears in the lowe
1e6f0 73 74 20 6c 65 76 65 6c 20 72 75 6e 20 62 65 69  st level run bei
1e700 6e 67 20 6d 65 72 67 65 64 2e 20 49 66 20 73 6f  ng merged. If so
1e710 2c 20 73 65 74 20 0a 20 20 2a 2a 20 69 50 74 72  , set .  ** iPtr
1e720 20 74 6f 20 74 68 65 20 61 62 73 6f 6c 75 74 65   to the absolute
1e730 20 70 6f 69 6e 74 65 72 20 76 61 6c 75 65 2e 20   pointer value. 
1e740 49 66 20 6e 6f 74 2c 20 6c 65 61 76 65 20 69 50  If not, leave iP
1e750 74 72 20 73 65 74 20 74 6f 20 7a 65 72 6f 2c 20  tr set to zero, 
1e760 0a 20 20 2a 2a 20 69 6e 64 69 63 61 74 69 6e 67  .  ** indicating
1e770 20 74 68 61 74 20 74 68 65 20 6f 75 74 70 75 74   that the output
1e780 20 70 6f 69 6e 74 65 72 20 76 61 6c 75 65 20 73   pointer value s
1e790 68 6f 75 6c 64 20 62 65 20 61 20 63 6f 70 79 20  hould be a copy 
1e7a0 6f 66 20 74 68 65 20 70 6f 69 6e 74 65 72 20 0a  of the pointer .
1e7b0 20 20 2a 2a 20 76 61 6c 75 65 20 77 72 69 74 74    ** value writt
1e7c0 65 6e 20 77 69 74 68 20 74 68 65 20 70 72 65 76  en with the prev
1e7d0 69 6f 75 73 20 6b 65 79 2e 20 20 2a 2f 0a 20 20  ious key.  */.  
1e7e0 69 50 74 72 20 3d 20 28 70 43 73 72 2d 3e 70 50  iPtr = (pCsr->pP
1e7f0 72 65 76 4d 65 72 67 65 50 74 72 20 3f 20 2a 70  revMergePtr ? *p
1e800 43 73 72 2d 3e 70 50 72 65 76 4d 65 72 67 65 50  Csr->pPrevMergeP
1e810 74 72 20 3a 20 30 29 3b 0a 20 20 69 66 28 20 70  tr : 0);.  if( p
1e820 43 73 72 2d 3e 70 42 74 43 73 72 20 29 7b 0a 20  Csr->pBtCsr ){. 
1e830 20 20 20 42 74 72 65 65 43 75 72 73 6f 72 20 2a     BtreeCursor *
1e840 70 42 74 43 73 72 20 3d 20 70 43 73 72 2d 3e 70  pBtCsr = pCsr->p
1e850 42 74 43 73 72 3b 0a 20 20 20 20 69 66 28 20 70  BtCsr;.    if( p
1e860 42 74 43 73 72 2d 3e 70 4b 65 79 20 29 7b 0a 20  BtCsr->pKey ){. 
1e870 20 20 20 20 20 69 6e 74 20 72 65 73 20 3d 20 72       int res = r
1e880 74 54 6f 70 69 63 28 70 42 74 43 73 72 2d 3e 65  tTopic(pBtCsr->e
1e890 54 79 70 65 29 20 2d 20 72 74 54 6f 70 69 63 28  Type) - rtTopic(
1e8a0 65 54 79 70 65 29 3b 0a 20 20 20 20 20 20 69 66  eType);.      if
1e8b0 28 20 72 65 73 3d 3d 30 20 29 20 72 65 73 20 3d  ( res==0 ) res =
1e8c0 20 70 44 62 2d 3e 78 43 6d 70 28 70 42 74 43 73   pDb->xCmp(pBtCs
1e8d0 72 2d 3e 70 4b 65 79 2c 20 70 42 74 43 73 72 2d  r->pKey, pBtCsr-
1e8e0 3e 6e 4b 65 79 2c 20 70 4b 65 79 2c 20 6e 4b 65  >nKey, pKey, nKe
1e8f0 79 29 3b 0a 20 20 20 20 20 20 69 66 28 20 30 3d  y);.      if( 0=
1e900 3d 72 65 73 20 29 20 69 50 74 72 20 3d 20 70 42  =res ) iPtr = pB
1e910 74 43 73 72 2d 3e 69 50 74 72 3b 0a 20 20 20 20  tCsr->iPtr;.    
1e920 20 20 61 73 73 65 72 74 28 20 72 65 73 3e 3d 30    assert( res>=0
1e930 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73   );.    }.  }els
1e940 65 20 69 66 28 20 70 43 73 72 2d 3e 6e 50 74 72  e if( pCsr->nPtr
1e950 20 29 7b 0a 20 20 20 20 53 65 67 6d 65 6e 74 50   ){.    SegmentP
1e960 74 72 20 2a 70 50 74 72 20 3d 20 26 70 43 73 72  tr *pPtr = &pCsr
1e970 2d 3e 61 50 74 72 5b 70 43 73 72 2d 3e 6e 50 74  ->aPtr[pCsr->nPt
1e980 72 2d 31 5d 3b 0a 20 20 20 20 69 66 28 20 70 50  r-1];.    if( pP
1e990 74 72 2d 3e 70 50 67 0a 20 20 20 20 20 26 26 20  tr->pPg.     && 
1e9a0 30 3d 3d 70 44 62 2d 3e 78 43 6d 70 28 70 50 74  0==pDb->xCmp(pPt
1e9b0 72 2d 3e 70 4b 65 79 2c 20 70 50 74 72 2d 3e 6e  r->pKey, pPtr->n
1e9c0 4b 65 79 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29  Key, pKey, nKey)
1e9d0 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 69 50  .    ){.      iP
1e9e0 74 72 20 3d 20 70 50 74 72 2d 3e 69 50 74 72 2b  tr = pPtr->iPtr+
1e9f0 70 50 74 72 2d 3e 69 50 67 50 74 72 3b 0a 20 20  pPtr->iPgPtr;.  
1ea00 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 56 61 6c 20    }.  }..  iVal 
1ea10 3d 20 70 43 73 72 2d 3e 61 54 72 65 65 5b 31 5d  = pCsr->aTree[1]
1ea20 3b 0a 20 20 6d 65 72 67 65 52 61 6e 67 65 44 65  ;.  mergeRangeDe
1ea30 6c 65 74 65 73 28 70 43 73 72 2c 20 26 69 56 61  letes(pCsr, &iVa
1ea40 6c 2c 20 26 65 54 79 70 65 29 3b 0a 0a 20 20 69  l, &eType);..  i
1ea50 66 28 20 65 54 79 70 65 21 3d 30 20 29 7b 0a 20  f( eType!=0 ){. 
1ea60 20 20 20 69 66 28 20 70 4d 57 2d 3e 61 47 6f 62     if( pMW->aGob
1ea70 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  ble ){.      int
1ea80 20 69 47 6f 62 62 6c 65 20 3d 20 70 43 73 72 2d   iGobble = pCsr-
1ea90 3e 61 54 72 65 65 5b 31 5d 20 2d 20 43 55 52 53  >aTree[1] - CURS
1eaa0 4f 52 5f 44 41 54 41 5f 53 45 47 4d 45 4e 54 3b  OR_DATA_SEGMENT;
1eab0 0a 20 20 20 20 20 20 69 66 28 20 69 47 6f 62 62  .      if( iGobb
1eac0 6c 65 3c 70 43 73 72 2d 3e 6e 50 74 72 20 26 26  le<pCsr->nPtr &&
1ead0 20 69 47 6f 62 62 6c 65 3e 3d 30 20 29 7b 0a 20   iGobble>=0 ){. 
1eae0 20 20 20 20 20 20 20 53 65 67 6d 65 6e 74 50 74         SegmentPt
1eaf0 72 20 2a 70 47 6f 62 62 6c 65 20 3d 20 26 70 43  r *pGobble = &pC
1eb00 73 72 2d 3e 61 50 74 72 5b 69 47 6f 62 62 6c 65  sr->aPtr[iGobble
1eb10 5d 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 28  ];.        if( (
1eb20 70 47 6f 62 62 6c 65 2d 3e 66 6c 61 67 73 20 26  pGobble->flags &
1eb30 20 50 47 46 54 52 5f 53 4b 49 50 5f 54 48 49 53   PGFTR_SKIP_THIS
1eb40 5f 46 4c 41 47 29 3d 3d 30 20 29 7b 0a 20 20 20  _FLAG)==0 ){.   
1eb50 20 20 20 20 20 20 20 70 4d 57 2d 3e 61 47 6f 62         pMW->aGob
1eb60 62 6c 65 5b 69 47 6f 62 62 6c 65 5d 20 3d 20 6c  ble[iGobble] = l
1eb70 73 6d 46 73 50 61 67 65 4e 75 6d 62 65 72 28 70  smFsPageNumber(p
1eb80 47 6f 62 62 6c 65 2d 3e 70 50 67 29 3b 0a 20 20  Gobble->pPg);.  
1eb90 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
1eba0 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66      }..    /* If
1ebb0 20 74 68 69 73 20 69 73 20 61 20 73 65 70 61 72   this is a separ
1ebc0 61 74 6f 72 20 6b 65 79 20 61 6e 64 20 77 65 20  ator key and we 
1ebd0 6b 6e 6f 77 20 74 68 61 74 20 74 68 65 20 6f 75  know that the ou
1ebe0 74 70 75 74 20 70 6f 69 6e 74 65 72 20 68 61 73  tput pointer has
1ebf0 20 6e 6f 74 0a 20 20 20 20 2a 2a 20 63 68 61 6e   not.    ** chan
1ec00 67 65 64 2c 20 74 68 65 72 65 20 69 73 20 6e 6f  ged, there is no
1ec10 20 70 6f 69 6e 74 20 69 6e 20 77 72 69 74 69 6e   point in writin
1ec20 67 20 61 6e 20 6f 75 74 70 75 74 20 72 65 63 6f  g an output reco
1ec30 72 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 0a 20  rd. Otherwise,. 
1ec40 20 20 20 2a 2a 20 70 72 6f 63 65 65 64 2e 20 2a     ** proceed. *
1ec50 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53  /.    if( rc==LS
1ec60 4d 5f 4f 4b 20 26 26 20 28 72 74 49 73 53 65 70  M_OK && (rtIsSep
1ec70 61 72 61 74 6f 72 28 65 54 79 70 65 29 3d 3d 30  arator(eType)==0
1ec80 20 7c 7c 20 69 50 74 72 21 3d 30 29 20 29 7b 0a   || iPtr!=0) ){.
1ec90 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74        /* Write t
1eca0 68 65 20 72 65 63 6f 72 64 20 69 6e 74 6f 20 74  he record into t
1ecb0 68 65 20 6d 61 69 6e 20 72 75 6e 2e 20 2a 2f 0a  he main run. */.
1ecc0 20 20 20 20 20 20 76 6f 69 64 20 2a 70 56 61 6c        void *pVal
1ecd0 3b 20 69 6e 74 20 6e 56 61 6c 3b 0a 20 20 20 20  ; int nVal;.    
1ece0 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75 72 73    rc = multiCurs
1ecf0 6f 72 47 65 74 56 61 6c 28 70 43 73 72 2c 20 69  orGetVal(pCsr, i
1ed00 56 61 6c 2c 20 26 70 56 61 6c 2c 20 26 6e 56 61  Val, &pVal, &nVa
1ed10 6c 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 56  l);.      if( pV
1ed20 61 6c 20 26 26 20 72 63 3d 3d 4c 53 4d 5f 4f 4b  al && rc==LSM_OK
1ed30 20 29 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65   ){.        asse
1ed40 72 74 28 20 6e 56 61 6c 3e 3d 30 20 29 3b 0a 20  rt( nVal>=0 );. 
1ed50 20 20 20 20 20 20 20 72 63 20 3d 20 73 6f 72 74         rc = sort
1ed60 65 64 42 6c 6f 62 53 65 74 28 70 44 62 2d 3e 70  edBlobSet(pDb->p
1ed70 45 6e 76 2c 20 26 70 43 73 72 2d 3e 76 61 6c 2c  Env, &pCsr->val,
1ed80 20 70 56 61 6c 2c 20 6e 56 61 6c 29 3b 0a 20 20   pVal, nVal);.  
1ed90 20 20 20 20 20 20 70 56 61 6c 20 3d 20 70 43 73        pVal = pCs
1eda0 72 2d 3e 76 61 6c 2e 70 44 61 74 61 3b 0a 20 20  r->val.pData;.  
1edb0 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
1edc0 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20  rc==LSM_OK ){.  
1edd0 20 20 20 20 20 20 72 63 20 3d 20 6d 65 72 67 65        rc = merge
1ede0 57 6f 72 6b 65 72 57 72 69 74 65 28 70 4d 57 2c  WorkerWrite(pMW,
1edf0 20 65 54 79 70 65 2c 20 70 4b 65 79 2c 20 6e 4b   eType, pKey, nK
1ee00 65 79 2c 20 70 56 61 6c 2c 20 6e 56 61 6c 2c 20  ey, pVal, nVal, 
1ee10 69 50 74 72 29 3b 0a 20 20 20 20 20 20 7d 0a 20  iPtr);.      }. 
1ee20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41     }.  }..  /* A
1ee30 64 76 61 6e 63 65 20 74 68 65 20 63 75 72 73 6f  dvance the curso
1ee40 72 20 74 6f 20 74 68 65 20 6e 65 78 74 20 69 6e  r to the next in
1ee50 70 75 74 20 72 65 63 6f 72 64 20 28 61 73 73 75  put record (assu
1ee60 6d 69 6e 67 20 6f 6e 65 20 65 78 69 73 74 73 29  ming one exists)
1ee70 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 6c  . */.  assert( l
1ee80 73 6d 4d 43 75 72 73 6f 72 56 61 6c 69 64 28 70  smMCursorValid(p
1ee90 4d 57 2d 3e 70 43 73 72 29 20 29 3b 0a 20 20 69  MW->pCsr) );.  i
1eea0 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 20  f( rc==LSM_OK ) 
1eeb0 72 63 20 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 4e  rc = lsmMCursorN
1eec0 65 78 74 28 70 4d 57 2d 3e 70 43 73 72 29 3b 0a  ext(pMW->pCsr);.
1eed0 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
1eee0 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 72 67  .static int merg
1eef0 65 57 6f 72 6b 65 72 44 6f 6e 65 28 4d 65 72 67  eWorkerDone(Merg
1ef00 65 57 6f 72 6b 65 72 20 2a 70 4d 57 29 7b 0a 20  eWorker *pMW){. 
1ef10 20 72 65 74 75 72 6e 20 70 4d 57 2d 3e 70 43 73   return pMW->pCs
1ef20 72 3d 3d 30 20 7c 7c 20 21 6c 73 6d 4d 43 75 72  r==0 || !lsmMCur
1ef30 73 6f 72 56 61 6c 69 64 28 70 4d 57 2d 3e 70 43  sorValid(pMW->pC
1ef40 73 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  sr);.}..static v
1ef50 6f 69 64 20 73 6f 72 74 65 64 46 72 65 65 4c 65  oid sortedFreeLe
1ef60 76 65 6c 28 6c 73 6d 5f 65 6e 76 20 2a 70 45 6e  vel(lsm_env *pEn
1ef70 76 2c 20 4c 65 76 65 6c 20 2a 70 29 7b 0a 20 20  v, Level *p){.  
1ef80 69 66 28 20 70 20 29 7b 0a 20 20 20 20 6c 73 6d  if( p ){.    lsm
1ef90 46 72 65 65 28 70 45 6e 76 2c 20 70 2d 3e 70 53  Free(pEnv, p->pS
1efa0 70 6c 69 74 4b 65 79 29 3b 0a 20 20 20 20 6c 73  plitKey);.    ls
1efb0 6d 46 72 65 65 28 70 45 6e 76 2c 20 70 2d 3e 70  mFree(pEnv, p->p
1efc0 4d 65 72 67 65 29 3b 0a 20 20 20 20 6c 73 6d 46  Merge);.    lsmF
1efd0 72 65 65 28 70 45 6e 76 2c 20 70 2d 3e 61 52 68  ree(pEnv, p->aRh
1efe0 73 29 3b 0a 20 20 20 20 6c 73 6d 46 72 65 65 28  s);.    lsmFree(
1eff0 70 45 6e 76 2c 20 70 29 3b 0a 20 20 7d 0a 7d 0a  pEnv, p);.  }.}.
1f000 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 6f 72  .static void sor
1f010 74 65 64 49 6e 76 6f 6b 65 57 6f 72 6b 48 6f 6f  tedInvokeWorkHoo
1f020 6b 28 6c 73 6d 5f 64 62 20 2a 70 44 62 29 7b 0a  k(lsm_db *pDb){.
1f030 20 20 69 66 28 20 70 44 62 2d 3e 78 57 6f 72 6b    if( pDb->xWork
1f040 20 29 7b 0a 20 20 20 20 70 44 62 2d 3e 78 57 6f   ){.    pDb->xWo
1f050 72 6b 28 70 44 62 2c 20 70 44 62 2d 3e 70 57 6f  rk(pDb, pDb->pWo
1f060 72 6b 43 74 78 29 3b 0a 20 20 7d 0a 7d 0a 0a 73  rkCtx);.  }.}..s
1f070 74 61 74 69 63 20 69 6e 74 20 73 6f 72 74 65 64  tatic int sorted
1f080 4e 65 77 54 6f 70 6c 65 76 65 6c 28 0a 20 20 6c  NewToplevel(.  l
1f090 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20 20 20  sm_db *pDb,     
1f0a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1f0b0 2a 20 43 6f 6e 6e 65 63 74 69 6f 6e 20 68 61 6e  * Connection han
1f0c0 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 65 54 72  dle */.  int eTr
1f0d0 65 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ee,             
1f0e0 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20           /* One 
1f0f0 6f 66 20 74 68 65 20 54 52 45 45 5f 58 58 58 20  of the TREE_XXX 
1f100 63 6f 6e 73 74 61 6e 74 73 20 2a 2f 0a 20 20 69  constants */.  i
1f110 6e 74 20 2a 70 6e 57 72 69 74 65 20 20 20 20 20  nt *pnWrite     
1f120 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1f130 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66  * OUT: Number of
1f140 20 64 61 74 61 62 61 73 65 20 70 61 67 65 73 20   database pages 
1f150 77 72 69 74 74 65 6e 20 2a 2f 0a 29 7b 0a 20 20  written */.){.  
1f160 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b  int rc = LSM_OK;
1f170 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f180 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a  /* Return Code *
1f190 2f 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  /.  MultiCursor 
1f1a0 2a 70 43 73 72 20 3d 20 30 3b 0a 20 20 4c 65 76  *pCsr = 0;.  Lev
1f1b0 65 6c 20 2a 70 4e 65 78 74 20 3d 20 30 3b 20 20  el *pNext = 0;  
1f1c0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1f1d0 54 68 65 20 63 75 72 72 65 6e 74 20 74 6f 70 20  The current top 
1f1e0 6c 65 76 65 6c 20 2a 2f 0a 20 20 4c 65 76 65 6c  level */.  Level
1f1f0 20 2a 70 4e 65 77 3b 20 20 20 20 20 20 20 20 20   *pNew;         
1f200 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
1f210 65 20 6e 65 77 20 6c 65 76 65 6c 20 69 74 73 65  e new level itse
1f220 6c 66 20 2a 2f 0a 20 20 53 65 67 6d 65 6e 74 20  lf */.  Segment 
1f230 2a 70 4c 69 6e 6b 65 64 20 3d 20 30 3b 20 20 20  *pLinked = 0;   
1f240 20 20 20 20 20 20 20 20 2f 2a 20 44 65 6c 65 74          /* Delet
1f250 65 20 73 65 70 61 72 61 74 6f 72 73 20 66 72 6f  e separators fro
1f260 6d 20 74 68 69 73 20 73 65 67 6d 65 6e 74 20 2a  m this segment *
1f270 2f 0a 20 20 4c 65 76 65 6c 20 2a 70 44 65 6c 20  /.  Level *pDel 
1f280 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
1f290 20 20 20 20 2f 2a 20 44 65 6c 65 74 65 20 74 68      /* Delete th
1f2a0 69 73 20 65 6e 74 69 72 65 20 6c 65 76 65 6c 20  is entire level 
1f2b0 2a 2f 0a 20 20 69 6e 74 20 6e 57 72 69 74 65 20  */.  int nWrite 
1f2c0 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
1f2d0 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
1f2e0 66 20 64 61 74 61 62 61 73 65 20 70 61 67 65 73  f database pages
1f2f0 20 77 72 69 74 74 65 6e 20 2a 2f 0a 20 20 46 72   written */.  Fr
1f300 65 65 6c 69 73 74 20 66 72 65 65 6c 69 73 74 3b  eelist freelist;
1f310 0a 0a 20 20 69 66 28 20 65 54 72 65 65 21 3d 54  ..  if( eTree!=T
1f320 52 45 45 5f 4e 4f 4e 45 20 29 7b 0a 20 20 20 20  REE_NONE ){.    
1f330 72 63 20 3d 20 6c 73 6d 53 68 6d 43 61 63 68 65  rc = lsmShmCache
1f340 43 68 75 6e 6b 73 28 70 44 62 2c 20 70 44 62 2d  Chunks(pDb, pDb-
1f350 3e 74 72 65 65 68 64 72 2e 6e 43 68 75 6e 6b 29  >treehdr.nChunk)
1f360 3b 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28  ;.  }..  assert(
1f370 20 70 44 62 2d 3e 62 55 73 65 46 72 65 65 6c 69   pDb->bUseFreeli
1f380 73 74 3d 3d 30 20 29 3b 0a 20 20 70 44 62 2d 3e  st==0 );.  pDb->
1f390 70 46 72 65 65 6c 69 73 74 20 3d 20 26 66 72 65  pFreelist = &fre
1f3a0 65 6c 69 73 74 3b 0a 20 20 70 44 62 2d 3e 62 55  elist;.  pDb->bU
1f3b0 73 65 46 72 65 65 6c 69 73 74 20 3d 20 31 3b 0a  seFreelist = 1;.
1f3c0 20 20 6d 65 6d 73 65 74 28 26 66 72 65 65 6c 69    memset(&freeli
1f3d0 73 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 66 72  st, 0, sizeof(fr
1f3e0 65 65 6c 69 73 74 29 29 3b 0a 0a 20 20 2f 2a 20  eelist));..  /* 
1f3f0 41 6c 6c 6f 63 61 74 65 20 74 68 65 20 6e 65 77  Allocate the new
1f400 20 6c 65 76 65 6c 20 73 74 72 75 63 74 75 72 65   level structure
1f410 20 74 6f 20 77 72 69 74 65 20 74 6f 2e 20 2a 2f   to write to. */
1f420 0a 20 20 70 4e 65 78 74 20 3d 20 6c 73 6d 44 62  .  pNext = lsmDb
1f430 53 6e 61 70 73 68 6f 74 4c 65 76 65 6c 28 70 44  SnapshotLevel(pD
1f440 62 2d 3e 70 57 6f 72 6b 65 72 29 3b 0a 20 20 70  b->pWorker);.  p
1f450 4e 65 77 20 3d 20 28 4c 65 76 65 6c 20 2a 29 6c  New = (Level *)l
1f460 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28 70  smMallocZeroRc(p
1f470 44 62 2d 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66  Db->pEnv, sizeof
1f480 28 4c 65 76 65 6c 29 2c 20 26 72 63 29 3b 0a 20  (Level), &rc);. 
1f490 20 69 66 28 20 70 4e 65 77 20 29 7b 0a 20 20 20   if( pNew ){.   
1f4a0 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20 3d 20 70   pNew->pNext = p
1f4b0 4e 65 78 74 3b 0a 20 20 20 20 6c 73 6d 44 62 53  Next;.    lsmDbS
1f4c0 6e 61 70 73 68 6f 74 53 65 74 4c 65 76 65 6c 28  napshotSetLevel(
1f4d0 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2c 20 70 4e  pDb->pWorker, pN
1f4e0 65 77 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43  ew);.  }..  /* C
1f4f0 72 65 61 74 65 20 61 20 63 75 72 73 6f 72 20 74  reate a cursor t
1f500 6f 20 67 61 74 68 65 72 20 74 68 65 20 64 61 74  o gather the dat
1f510 61 20 72 65 71 75 69 72 65 64 20 62 79 20 74 68  a required by th
1f520 65 20 6e 65 77 20 73 65 67 6d 65 6e 74 2e 20 54  e new segment. T
1f530 68 65 20 6e 65 77 0a 20 20 2a 2a 20 73 65 67 6d  he new.  ** segm
1f540 65 6e 74 20 63 6f 6e 74 61 69 6e 73 20 65 76 65  ent contains eve
1f550 72 79 74 68 69 6e 67 20 69 6e 20 74 68 65 20 74  rything in the t
1f560 72 65 65 20 61 6e 64 20 70 6f 69 6e 74 65 72 73  ree and pointers
1f570 20 74 6f 20 74 68 65 20 6e 65 78 74 20 73 65 67   to the next seg
1f580 6d 65 6e 74 0a 20 20 2a 2a 20 69 6e 20 74 68 65  ment.  ** in the
1f590 20 64 61 74 61 62 61 73 65 20 28 69 66 20 61 6e   database (if an
1f5a0 79 29 2e 20 20 2a 2f 0a 20 20 70 43 73 72 20 3d  y).  */.  pCsr =
1f5b0 20 6d 75 6c 74 69 43 75 72 73 6f 72 4e 65 77 28   multiCursorNew(
1f5c0 70 44 62 2c 20 26 72 63 29 3b 0a 20 20 69 66 28  pDb, &rc);.  if(
1f5d0 20 70 43 73 72 20 29 7b 0a 20 20 20 20 70 43 73   pCsr ){.    pCs
1f5e0 72 2d 3e 70 44 62 20 3d 20 70 44 62 3b 0a 20 20  r->pDb = pDb;.  
1f5f0 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75 72 73    rc = multiCurs
1f600 6f 72 56 69 73 69 74 46 72 65 65 6c 69 73 74 28  orVisitFreelist(
1f610 70 43 73 72 29 3b 0a 20 20 20 20 69 66 28 20 72  pCsr);.    if( r
1f620 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
1f630 20 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75 72     rc = multiCur
1f640 73 6f 72 41 64 64 54 72 65 65 28 70 43 73 72 2c  sorAddTree(pCsr,
1f650 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2c 20 65   pDb->pWorker, e
1f660 54 72 65 65 29 3b 0a 20 20 20 20 7d 0a 20 20 20  Tree);.    }.   
1f670 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
1f680 26 26 20 70 4e 65 78 74 20 26 26 20 70 4e 65 78  && pNext && pNex
1f690 74 2d 3e 70 4d 65 72 67 65 3d 3d 30 20 29 7b 0a  t->pMerge==0 ){.
1f6a0 20 20 20 20 20 20 69 66 28 20 28 70 4e 65 78 74        if( (pNext
1f6b0 2d 3e 66 6c 61 67 73 20 26 20 4c 45 56 45 4c 5f  ->flags & LEVEL_
1f6c0 46 52 45 45 4c 49 53 54 5f 4f 4e 4c 59 29 20 29  FREELIST_ONLY) )
1f6d0 7b 0a 20 20 20 20 20 20 20 20 70 44 65 6c 20 3d  {.        pDel =
1f6e0 20 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20   pNext;.        
1f6f0 70 43 73 72 2d 3e 61 50 74 72 20 3d 20 6c 73 6d  pCsr->aPtr = lsm
1f700 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28 70 44 62  MallocZeroRc(pDb
1f710 2d 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66 28 53  ->pEnv, sizeof(S
1f720 65 67 6d 65 6e 74 50 74 72 29 2c 20 26 72 63 29  egmentPtr), &rc)
1f730 3b 0a 20 20 20 20 20 20 20 20 6d 75 6c 74 69 43  ;.        multiC
1f740 75 72 73 6f 72 41 64 64 4f 6e 65 28 70 43 73 72  ursorAddOne(pCsr
1f750 2c 20 70 4e 65 78 74 2c 20 26 72 63 29 3b 0a 20  , pNext, &rc);. 
1f760 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 65       }else if( e
1f770 54 72 65 65 21 3d 54 52 45 45 5f 4e 4f 4e 45 20  Tree!=TREE_NONE 
1f780 26 26 20 70 4e 65 78 74 2d 3e 6c 68 73 2e 69 52  && pNext->lhs.iR
1f790 6f 6f 74 20 29 7b 0a 20 20 20 20 20 20 20 20 70  oot ){.        p
1f7a0 4c 69 6e 6b 65 64 20 3d 20 26 70 4e 65 78 74 2d  Linked = &pNext-
1f7b0 3e 6c 68 73 3b 0a 20 20 20 20 20 20 20 20 72 63  >lhs;.        rc
1f7c0 20 3d 20 62 74 72 65 65 43 75 72 73 6f 72 4e 65   = btreeCursorNe
1f7d0 77 28 70 44 62 2c 20 70 4c 69 6e 6b 65 64 2c 20  w(pDb, pLinked, 
1f7e0 26 70 43 73 72 2d 3e 70 42 74 43 73 72 29 3b 0a  &pCsr->pBtCsr);.
1f7f0 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
1f800 20 20 20 2f 2a 20 49 66 20 74 68 69 73 20 77 69     /* If this wi
1f810 6c 6c 20 62 65 20 74 68 65 20 6f 6e 6c 79 20 73  ll be the only s
1f820 65 67 6d 65 6e 74 20 69 6e 20 74 68 65 20 64 61  egment in the da
1f830 74 61 62 61 73 65 2c 20 64 69 73 63 61 72 64 20  tabase, discard 
1f840 61 6e 79 20 64 65 6c 65 74 65 0a 20 20 20 20 2a  any delete.    *
1f850 2a 20 6d 61 72 6b 65 72 73 20 70 72 65 73 65 6e  * markers presen
1f860 74 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65 6d 6f  t in the in-memo
1f870 72 79 20 74 72 65 65 2e 20 20 2a 2f 0a 20 20 20  ry tree.  */.   
1f880 20 69 66 28 20 70 4e 65 78 74 3d 3d 30 20 29 7b   if( pNext==0 ){
1f890 0a 20 20 20 20 20 20 6d 75 6c 74 69 43 75 72 73  .      multiCurs
1f8a0 6f 72 49 67 6e 6f 72 65 44 65 6c 65 74 65 28 70  orIgnoreDelete(p
1f8b0 43 73 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  Csr);.    }.  }.
1f8c0 0a 20 20 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f  .  if( rc!=LSM_O
1f8d0 4b 20 29 7b 0a 20 20 20 20 6c 73 6d 4d 43 75 72  K ){.    lsmMCur
1f8e0 73 6f 72 43 6c 6f 73 65 28 70 43 73 72 2c 20 30  sorClose(pCsr, 0
1f8f0 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
1f900 50 67 6e 6f 20 69 4c 65 66 74 50 74 72 20 3d 20  Pgno iLeftPtr = 
1f910 30 3b 0a 20 20 20 20 4d 65 72 67 65 20 6d 65 72  0;.    Merge mer
1f920 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
1f930 20 20 20 20 20 2f 2a 20 4d 65 72 67 65 20 6f 62       /* Merge ob
1f940 6a 65 63 74 20 75 73 65 64 20 74 6f 20 63 72 65  ject used to cre
1f950 61 74 65 20 6e 65 77 20 6c 65 76 65 6c 20 2a 2f  ate new level */
1f960 0a 20 20 20 20 4d 65 72 67 65 57 6f 72 6b 65 72  .    MergeWorker
1f970 20 6d 65 72 67 65 77 6f 72 6b 65 72 3b 20 20 20   mergeworker;   
1f980 20 20 20 2f 2a 20 4d 65 72 67 65 57 6f 72 6b 65     /* MergeWorke
1f990 72 20 6f 62 6a 65 63 74 20 66 6f 72 20 74 68 65  r object for the
1f9a0 20 73 61 6d 65 20 70 75 72 70 6f 73 65 20 2a 2f   same purpose */
1f9b0 0a 0a 20 20 20 20 6d 65 6d 73 65 74 28 26 6d 65  ..    memset(&me
1f9c0 72 67 65 2c 20 30 2c 20 73 69 7a 65 6f 66 28 4d  rge, 0, sizeof(M
1f9d0 65 72 67 65 29 29 3b 0a 20 20 20 20 6d 65 6d 73  erge));.    mems
1f9e0 65 74 28 26 6d 65 72 67 65 77 6f 72 6b 65 72 2c  et(&mergeworker,
1f9f0 20 30 2c 20 73 69 7a 65 6f 66 28 4d 65 72 67 65   0, sizeof(Merge
1fa00 57 6f 72 6b 65 72 29 29 3b 0a 0a 20 20 20 20 70  Worker));..    p
1fa10 4e 65 77 2d 3e 70 4d 65 72 67 65 20 3d 20 26 6d  New->pMerge = &m
1fa20 65 72 67 65 3b 0a 20 20 20 20 70 4e 65 77 2d 3e  erge;.    pNew->
1fa30 66 6c 61 67 73 20 7c 3d 20 4c 45 56 45 4c 5f 49  flags |= LEVEL_I
1fa40 4e 43 4f 4d 50 4c 45 54 45 3b 0a 20 20 20 20 6d  NCOMPLETE;.    m
1fa50 65 72 67 65 77 6f 72 6b 65 72 2e 70 44 62 20 3d  ergeworker.pDb =
1fa60 20 70 44 62 3b 0a 20 20 20 20 6d 65 72 67 65 77   pDb;.    mergew
1fa70 6f 72 6b 65 72 2e 70 4c 65 76 65 6c 20 3d 20 70  orker.pLevel = p
1fa80 4e 65 77 3b 0a 20 20 20 20 6d 65 72 67 65 77 6f  New;.    mergewo
1fa90 72 6b 65 72 2e 70 43 73 72 20 3d 20 70 43 73 72  rker.pCsr = pCsr
1faa0 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 50 72 65  ;.    pCsr->pPre
1fab0 76 4d 65 72 67 65 50 74 72 20 3d 20 26 69 4c 65  vMergePtr = &iLe
1fac0 66 74 50 74 72 3b 0a 0a 20 20 20 20 2f 2a 20 4d  ftPtr;..    /* M
1fad0 61 72 6b 20 74 68 65 20 73 65 70 61 72 61 74 6f  ark the separato
1fae0 72 73 20 61 72 72 61 79 20 66 6f 72 20 74 68 65  rs array for the
1faf0 20 6e 65 77 20 6c 65 76 65 6c 20 61 73 20 61 20   new level as a 
1fb00 22 70 68 61 6e 74 6f 6d 22 2e 20 2a 2f 0a 20 20  "phantom". */.  
1fb10 20 20 6d 65 72 67 65 77 6f 72 6b 65 72 2e 62 46    mergeworker.bF
1fb20 6c 75 73 68 20 3d 20 31 3b 0a 0a 20 20 20 20 2f  lush = 1;..    /
1fb30 2a 20 44 6f 20 74 68 65 20 77 6f 72 6b 20 74 6f  * Do the work to
1fb40 20 63 72 65 61 74 65 20 74 68 65 20 6e 65 77 20   create the new 
1fb50 6d 65 72 67 65 64 20 73 65 67 6d 65 6e 74 20 6f  merged segment o
1fb60 6e 20 64 69 73 6b 20 2a 2f 0a 20 20 20 20 69 66  n disk */.    if
1fb70 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 20 72  ( rc==LSM_OK ) r
1fb80 63 20 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 46 69  c = lsmMCursorFi
1fb90 72 73 74 28 70 43 73 72 29 3b 0a 20 20 20 20 77  rst(pCsr);.    w
1fba0 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b  hile( rc==LSM_OK
1fbb0 20 26 26 20 6d 65 72 67 65 57 6f 72 6b 65 72 44   && mergeWorkerD
1fbc0 6f 6e 65 28 26 6d 65 72 67 65 77 6f 72 6b 65 72  one(&mergeworker
1fbd0 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63  )==0 ){.      rc
1fbe0 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65 72 53 74   = mergeWorkerSt
1fbf0 65 70 28 26 6d 65 72 67 65 77 6f 72 6b 65 72 29  ep(&mergeworker)
1fc00 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 72 67  ;.    }.    merg
1fc10 65 57 6f 72 6b 65 72 53 68 75 74 64 6f 77 6e 28  eWorkerShutdown(
1fc20 26 6d 65 72 67 65 77 6f 72 6b 65 72 2c 20 26 72  &mergeworker, &r
1fc30 63 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  c);.    assert( 
1fc40 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 6d 65  rc!=LSM_OK || me
1fc50 72 67 65 77 6f 72 6b 65 72 2e 6e 57 6f 72 6b 3d  rgeworker.nWork=
1fc60 3d 30 20 7c 7c 20 70 4e 65 77 2d 3e 6c 68 73 2e  =0 || pNew->lhs.
1fc70 69 46 69 72 73 74 20 29 3b 0a 20 20 20 20 69 66  iFirst );.    if
1fc80 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20  ( rc==LSM_OK && 
1fc90 70 4e 65 77 2d 3e 6c 68 73 2e 69 46 69 72 73 74  pNew->lhs.iFirst
1fca0 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 6c   ){.      rc = l
1fcb0 73 6d 46 73 53 6f 72 74 65 64 46 69 6e 69 73 68  smFsSortedFinish
1fcc0 28 70 44 62 2d 3e 70 46 53 2c 20 26 70 4e 65 77  (pDb->pFS, &pNew
1fcd0 2d 3e 6c 68 73 29 3b 0a 20 20 20 20 7d 0a 20 20  ->lhs);.    }.  
1fce0 20 20 6e 57 72 69 74 65 20 3d 20 6d 65 72 67 65    nWrite = merge
1fcf0 77 6f 72 6b 65 72 2e 6e 57 6f 72 6b 3b 0a 20 20  worker.nWork;.  
1fd00 20 20 70 4e 65 77 2d 3e 66 6c 61 67 73 20 26 3d    pNew->flags &=
1fd10 20 7e 4c 45 56 45 4c 5f 49 4e 43 4f 4d 50 4c 45   ~LEVEL_INCOMPLE
1fd20 54 45 3b 0a 20 20 20 20 69 66 28 20 65 54 72 65  TE;.    if( eTre
1fd30 65 3d 3d 54 52 45 45 5f 4e 4f 4e 45 20 29 7b 0a  e==TREE_NONE ){.
1fd40 20 20 20 20 20 20 70 4e 65 77 2d 3e 66 6c 61 67        pNew->flag
1fd50 73 20 7c 3d 20 4c 45 56 45 4c 5f 46 52 45 45 4c  s |= LEVEL_FREEL
1fd60 49 53 54 5f 4f 4e 4c 59 3b 0a 20 20 20 20 7d 0a  IST_ONLY;.    }.
1fd70 20 20 20 20 70 4e 65 77 2d 3e 70 4d 65 72 67 65      pNew->pMerge
1fd80 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 69 66 28   = 0;.  }..  if(
1fd90 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 70   rc!=LSM_OK || p
1fda0 4e 65 77 2d 3e 6c 68 73 2e 69 46 69 72 73 74 3d  New->lhs.iFirst=
1fdb0 3d 30 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74  =0 ){.    assert
1fdc0 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20  ( rc!=LSM_OK || 
1fdd0 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2d 3e 66 72  pDb->pWorker->fr
1fde0 65 65 6c 69 73 74 2e 6e 45 6e 74 72 79 3d 3d 30  eelist.nEntry==0
1fdf0 20 29 3b 0a 20 20 20 20 6c 73 6d 44 62 53 6e 61   );.    lsmDbSna
1fe00 70 73 68 6f 74 53 65 74 4c 65 76 65 6c 28 70 44  pshotSetLevel(pD
1fe10 62 2d 3e 70 57 6f 72 6b 65 72 2c 20 70 4e 65 78  b->pWorker, pNex
1fe20 74 29 3b 0a 20 20 20 20 73 6f 72 74 65 64 46 72  t);.    sortedFr
1fe30 65 65 4c 65 76 65 6c 28 70 44 62 2d 3e 70 45 6e  eeLevel(pDb->pEn
1fe40 76 2c 20 70 4e 65 77 29 3b 0a 20 20 7d 65 6c 73  v, pNew);.  }els
1fe50 65 7b 0a 20 20 20 20 69 66 28 20 70 4c 69 6e 6b  e{.    if( pLink
1fe60 65 64 20 29 7b 0a 20 20 20 20 20 20 70 4c 69 6e  ed ){.      pLin
1fe70 6b 65 64 2d 3e 69 52 6f 6f 74 20 3d 20 30 3b 0a  ked->iRoot = 0;.
1fe80 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70 44      }else if( pD
1fe90 65 6c 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65  el ){.      asse
1fea0 72 74 28 20 70 4e 65 77 2d 3e 70 4e 65 78 74 3d  rt( pNew->pNext=
1feb0 3d 70 44 65 6c 20 29 3b 0a 20 20 20 20 20 20 70  =pDel );.      p
1fec0 4e 65 77 2d 3e 70 4e 65 78 74 20 3d 20 70 44 65  New->pNext = pDe
1fed0 6c 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  l->pNext;.      
1fee0 6c 73 6d 46 73 53 6f 72 74 65 64 44 65 6c 65 74  lsmFsSortedDelet
1fef0 65 28 70 44 62 2d 3e 70 46 53 2c 20 70 44 62 2d  e(pDb->pFS, pDb-
1ff00 3e 70 57 6f 72 6b 65 72 2c 20 31 2c 20 26 70 44  >pWorker, 1, &pD
1ff10 65 6c 2d 3e 6c 68 73 29 3b 0a 20 20 20 20 20 20  el->lhs);.      
1ff20 73 6f 72 74 65 64 46 72 65 65 4c 65 76 65 6c 28  sortedFreeLevel(
1ff30 70 44 62 2d 3e 70 45 6e 76 2c 20 70 44 65 6c 29  pDb->pEnv, pDel)
1ff40 3b 0a 20 20 20 20 7d 0a 0a 23 69 66 20 4c 53 4d  ;.    }..#if LSM
1ff50 5f 4c 4f 47 5f 53 54 52 55 43 54 55 52 45 0a 20  _LOG_STRUCTURE. 
1ff60 20 20 20 6c 73 6d 53 6f 72 74 65 64 44 75 6d 70     lsmSortedDump
1ff70 53 74 72 75 63 74 75 72 65 28 70 44 62 2c 20 70  Structure(pDb, p
1ff80 44 62 2d 3e 70 57 6f 72 6b 65 72 2c 20 4c 53 4d  Db->pWorker, LSM
1ff90 5f 4c 4f 47 5f 44 41 54 41 2c 20 30 2c 20 22 6e  _LOG_DATA, 0, "n
1ffa0 65 77 2d 74 6f 70 6c 65 76 65 6c 22 29 3b 0a 23  ew-toplevel");.#
1ffb0 65 6e 64 69 66 0a 0a 20 20 20 20 69 66 28 20 66  endif..    if( f
1ffc0 72 65 65 6c 69 73 74 2e 6e 45 6e 74 72 79 20 29  reelist.nEntry )
1ffd0 7b 0a 20 20 20 20 20 20 46 72 65 65 6c 69 73 74  {.      Freelist
1ffe0 20 2a 70 20 3d 20 26 70 44 62 2d 3e 70 57 6f 72   *p = &pDb->pWor
1fff0 6b 65 72 2d 3e 66 72 65 65 6c 69 73 74 3b 0a 20  ker->freelist;. 
20000 20 20 20 20 20 6c 73 6d 46 72 65 65 28 70 44 62       lsmFree(pDb
20010 2d 3e 70 45 6e 76 2c 20 70 2d 3e 61 45 6e 74 72  ->pEnv, p->aEntr
20020 79 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79  y);.      memcpy
20030 28 70 2c 20 26 66 72 65 65 6c 69 73 74 2c 20 73  (p, &freelist, s
20040 69 7a 65 6f 66 28 66 72 65 65 6c 69 73 74 29 29  izeof(freelist))
20050 3b 0a 20 20 20 20 20 20 66 72 65 65 6c 69 73 74  ;.      freelist
20060 2e 61 45 6e 74 72 79 20 3d 20 30 3b 0a 20 20 20  .aEntry = 0;.   
20070 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 44   }else{.      pD
20080 62 2d 3e 70 57 6f 72 6b 65 72 2d 3e 66 72 65 65  b->pWorker->free
20090 6c 69 73 74 2e 6e 45 6e 74 72 79 20 3d 20 30 3b  list.nEntry = 0;
200a0 0a 20 20 20 20 7d 0a 0a 20 20 20 20 61 73 73 65  .    }..    asse
200b0 72 74 42 74 72 65 65 4f 6b 28 70 44 62 2c 20 26  rtBtreeOk(pDb, &
200c0 70 4e 65 77 2d 3e 6c 68 73 29 3b 0a 20 20 20 20  pNew->lhs);.    
200d0 73 6f 72 74 65 64 49 6e 76 6f 6b 65 57 6f 72 6b  sortedInvokeWork
200e0 48 6f 6f 6b 28 70 44 62 29 3b 0a 20 20 7d 0a 0a  Hook(pDb);.  }..
200f0 20 20 69 66 28 20 70 6e 57 72 69 74 65 20 29 20    if( pnWrite ) 
20100 2a 70 6e 57 72 69 74 65 20 3d 20 6e 57 72 69 74  *pnWrite = nWrit
20110 65 3b 0a 20 20 70 44 62 2d 3e 70 57 6f 72 6b 65  e;.  pDb->pWorke
20120 72 2d 3e 6e 57 72 69 74 65 20 2b 3d 20 6e 57 72  r->nWrite += nWr
20130 69 74 65 3b 0a 20 20 70 44 62 2d 3e 70 46 72 65  ite;.  pDb->pFre
20140 65 6c 69 73 74 20 3d 20 30 3b 0a 20 20 70 44 62  elist = 0;.  pDb
20150 2d 3e 62 55 73 65 46 72 65 65 6c 69 73 74 20 3d  ->bUseFreelist =
20160 20 30 3b 0a 20 20 6c 73 6d 46 72 65 65 28 70 44   0;.  lsmFree(pD
20170 62 2d 3e 70 45 6e 76 2c 20 66 72 65 65 6c 69 73  b->pEnv, freelis
20180 74 2e 61 45 6e 74 72 79 29 3b 0a 20 20 72 65 74  t.aEntry);.  ret
20190 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
201a0 20 54 68 65 20 6e 4d 65 72 67 65 20 6c 65 76 65   The nMerge leve
201b0 6c 73 20 69 6e 20 74 68 65 20 4c 53 4d 20 62 65  ls in the LSM be
201c0 67 69 6e 6e 69 6e 67 20 77 69 74 68 20 70 4c 65  ginning with pLe
201d0 76 65 6c 20 63 6f 6e 73 69 73 74 20 6f 66 20 61  vel consist of a
201e0 0a 2a 2a 20 6c 65 66 74 2d 68 61 6e 64 2d 73 69  .** left-hand-si
201f0 64 65 20 73 65 67 6d 65 6e 74 20 6f 6e 6c 79 2e  de segment only.
20200 20 52 65 70 6c 61 63 65 20 74 68 65 73 65 20 6c   Replace these l
20210 65 76 65 6c 73 20 77 69 74 68 20 61 20 73 69 6e  evels with a sin
20220 67 6c 65 20 6e 65 77 0a 2a 2a 20 6c 65 76 65 6c  gle new.** level
20230 20 63 6f 6e 73 69 73 74 69 6e 67 20 6f 66 20 61   consisting of a
20240 20 6e 65 77 20 65 6d 70 74 79 20 73 65 67 6d 65   new empty segme
20250 6e 74 20 6f 6e 20 74 68 65 20 6c 65 66 74 2d 68  nt on the left-h
20260 61 6e 64 2d 73 69 64 65 20 61 6e 64 20 74 68 65  and-side and the
20270 0a 2a 2a 20 6e 4d 65 72 67 65 20 73 65 67 6d 65  .** nMerge segme
20280 6e 74 73 20 66 72 6f 6d 20 74 68 65 20 72 65 70  nts from the rep
20290 6c 61 63 65 64 20 6c 65 76 65 6c 73 20 6f 6e 20  laced levels on 
202a0 74 68 65 20 72 69 67 68 74 2d 68 61 6e 64 2d 73  the right-hand-s
202b0 69 64 65 2e 0a 2a 2a 0a 2a 2a 20 41 6c 73 6f 2c  ide..**.** Also,
202c0 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64 20 70 6f   allocate and po
202d0 70 75 6c 61 74 65 20 61 20 4d 65 72 67 65 20 6f  pulate a Merge o
202e0 62 6a 65 63 74 20 61 6e 64 20 73 65 74 20 4c 65  bject and set Le
202f0 76 65 6c 2e 70 4d 65 72 67 65 20 74 6f 0a 2a 2a  vel.pMerge to.**
20300 20 70 6f 69 6e 74 20 74 6f 20 69 74 2e 0a 2a 2f   point to it..*/
20310 0a 73 74 61 74 69 63 20 69 6e 74 20 73 6f 72 74  .static int sort
20320 65 64 4d 65 72 67 65 53 65 74 75 70 28 0a 20 20  edMergeSetup(.  
20330 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20 20  lsm_db *pDb,    
20340 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20350 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64  /* Database hand
20360 6c 65 20 2a 2f 0a 20 20 4c 65 76 65 6c 20 2a 70  le */.  Level *p
20370 4c 65 76 65 6c 2c 20 20 20 20 20 20 20 20 20 20  Level,          
20380 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74          /* First
20390 20 6c 65 76 65 6c 20 74 6f 20 6d 65 72 67 65 20   level to merge 
203a0 2a 2f 0a 20 20 69 6e 74 20 6e 4d 65 72 67 65 2c  */.  int nMerge,
203b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
203c0 20 20 20 20 20 2f 2a 20 4d 65 72 67 65 20 74 68       /* Merge th
203d0 69 73 20 6d 61 6e 79 20 6c 65 76 65 6c 73 20 74  is many levels t
203e0 6f 67 65 74 68 65 72 20 2a 2f 0a 20 20 4c 65 76  ogether */.  Lev
203f0 65 6c 20 2a 2a 70 70 4e 65 77 20 20 20 20 20 20  el **ppNew      
20400 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
20410 4e 65 77 2c 20 6d 65 72 67 65 64 2c 20 6c 65 76  New, merged, lev
20420 65 6c 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  el */.){.  int r
20430 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20  c = LSM_OK;     
20440 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
20450 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 4c  turn Code */.  L
20460 65 76 65 6c 20 2a 70 4e 65 77 3b 20 20 20 20 20  evel *pNew;     
20470 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
20480 2a 20 4e 65 77 20 4c 65 76 65 6c 20 6f 62 6a 65  * New Level obje
20490 63 74 20 2a 2f 0a 20 20 69 6e 74 20 62 55 73 65  ct */.  int bUse
204a0 4e 65 78 74 20 3d 20 30 3b 20 20 20 20 20 20 20  Next = 0;       
204b0 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
204c0 74 6f 20 6c 69 6e 6b 20 69 6e 20 6e 65 78 74 20  to link in next 
204d0 73 65 70 61 72 61 74 6f 72 73 20 2a 2f 0a 20 20  separators */.  
204e0 4d 65 72 67 65 20 2a 70 4d 65 72 67 65 3b 20 20  Merge *pMerge;  
204f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20500 2f 2a 20 4e 65 77 20 4d 65 72 67 65 20 6f 62 6a  /* New Merge obj
20510 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79  ect */.  int nBy
20520 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  te;             
20530 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
20540 73 20 6f 66 20 73 70 61 63 65 20 61 6c 6c 6f 63  s of space alloc
20550 61 74 65 64 20 61 74 20 70 4d 65 72 67 65 20 2a  ated at pMerge *
20560 2f 0a 0a 23 69 66 64 65 66 20 4c 53 4d 5f 44 45  /..#ifdef LSM_DE
20570 42 55 47 0a 20 20 69 6e 74 20 69 4c 65 76 65 6c  BUG.  int iLevel
20580 3b 0a 20 20 4c 65 76 65 6c 20 2a 70 58 20 3d 20  ;.  Level *pX = 
20590 70 4c 65 76 65 6c 3b 0a 20 20 66 6f 72 28 69 4c  pLevel;.  for(iL
205a0 65 76 65 6c 3d 30 3b 20 69 4c 65 76 65 6c 3c 6e  evel=0; iLevel<n
205b0 4d 65 72 67 65 3b 20 69 4c 65 76 65 6c 2b 2b 29  Merge; iLevel++)
205c0 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 58  {.    assert( pX
205d0 2d 3e 6e 52 69 67 68 74 3d 3d 30 20 29 3b 0a 20  ->nRight==0 );. 
205e0 20 20 20 70 58 20 3d 20 70 58 2d 3e 70 4e 65 78     pX = pX->pNex
205f0 74 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20  t;.  }.#endif.. 
20600 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68 65   /* Allocate the
20610 20 6e 65 77 20 4c 65 76 65 6c 20 6f 62 6a 65 63   new Level objec
20620 74 20 2a 2f 0a 20 20 70 4e 65 77 20 3d 20 28 4c  t */.  pNew = (L
20630 65 76 65 6c 20 2a 29 6c 73 6d 4d 61 6c 6c 6f 63  evel *)lsmMalloc
20640 5a 65 72 6f 52 63 28 70 44 62 2d 3e 70 45 6e 76  ZeroRc(pDb->pEnv
20650 2c 20 73 69 7a 65 6f 66 28 4c 65 76 65 6c 29 2c  , sizeof(Level),
20660 20 26 72 63 29 3b 0a 20 20 69 66 28 20 70 4e 65   &rc);.  if( pNe
20670 77 20 29 7b 0a 20 20 20 20 70 4e 65 77 2d 3e 61  w ){.    pNew->a
20680 52 68 73 20 3d 20 28 53 65 67 6d 65 6e 74 20 2a  Rhs = (Segment *
20690 29 6c 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63  )lsmMallocZeroRc
206a0 28 70 44 62 2d 3e 70 45 6e 76 2c 20 0a 20 20 20  (pDb->pEnv, .   
206b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
206c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
206d0 20 20 20 20 20 6e 4d 65 72 67 65 20 2a 20 73 69       nMerge * si
206e0 7a 65 6f 66 28 53 65 67 6d 65 6e 74 29 2c 20 26  zeof(Segment), &
206f0 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 50  rc);.  }..  /* P
20700 6f 70 75 6c 61 74 65 20 74 68 65 20 6e 65 77 20  opulate the new 
20710 4c 65 76 65 6c 20 6f 62 6a 65 63 74 20 2a 2f 0a  Level object */.
20720 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
20730 20 29 7b 0a 20 20 20 20 4c 65 76 65 6c 20 2a 70   ){.    Level *p
20740 4e 65 78 74 20 3d 20 30 3b 20 20 20 20 20 20 20  Next = 0;       
20750 20 20 20 20 20 20 2f 2a 20 4c 65 76 65 6c 20 66        /* Level f
20760 6f 6c 6c 6f 77 69 6e 67 20 70 4e 65 77 20 2a 2f  ollowing pNew */
20770 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
20780 69 6e 74 20 62 46 72 65 65 4f 6e 6c 79 20 3d 20  int bFreeOnly = 
20790 31 3b 0a 20 20 20 20 4c 65 76 65 6c 20 2a 70 54  1;.    Level *pT
207a0 6f 70 4c 65 76 65 6c 3b 0a 20 20 20 20 4c 65 76  opLevel;.    Lev
207b0 65 6c 20 2a 70 20 3d 20 70 4c 65 76 65 6c 3b 0a  el *p = pLevel;.
207c0 20 20 20 20 4c 65 76 65 6c 20 2a 2a 70 70 3b 0a      Level **pp;.
207d0 20 20 20 20 70 4e 65 77 2d 3e 6e 52 69 67 68 74      pNew->nRight
207e0 20 3d 20 6e 4d 65 72 67 65 3b 0a 20 20 20 20 70   = nMerge;.    p
207f0 4e 65 77 2d 3e 69 41 67 65 20 3d 20 70 4c 65 76  New->iAge = pLev
20800 65 6c 2d 3e 69 41 67 65 2b 31 3b 0a 20 20 20 20  el->iAge+1;.    
20810 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 4d 65 72 67  for(i=0; i<nMerg
20820 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 61  e; i++){.      a
20830 73 73 65 72 74 28 20 70 2d 3e 6e 52 69 67 68 74  ssert( p->nRight
20840 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 4e 65  ==0 );.      pNe
20850 78 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20  xt = p->pNext;. 
20860 20 20 20 20 20 70 4e 65 77 2d 3e 61 52 68 73 5b       pNew->aRhs[
20870 69 5d 20 3d 20 70 2d 3e 6c 68 73 3b 0a 20 20 20  i] = p->lhs;.   
20880 20 20 20 69 66 28 20 28 70 2d 3e 66 6c 61 67 73     if( (p->flags
20890 20 26 20 4c 45 56 45 4c 5f 46 52 45 45 4c 49 53   & LEVEL_FREELIS
208a0 54 5f 4f 4e 4c 59 29 3d 3d 30 20 29 20 62 46 72  T_ONLY)==0 ) bFr
208b0 65 65 4f 6e 6c 79 20 3d 20 30 3b 0a 20 20 20 20  eeOnly = 0;.    
208c0 20 20 73 6f 72 74 65 64 46 72 65 65 4c 65 76 65    sortedFreeLeve
208d0 6c 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70 29 3b  l(pDb->pEnv, p);
208e0 0a 20 20 20 20 20 20 70 20 3d 20 70 4e 65 78 74  .      p = pNext
208f0 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  ;.    }..    if(
20900 20 62 46 72 65 65 4f 6e 6c 79 20 29 20 70 4e 65   bFreeOnly ) pNe
20910 77 2d 3e 66 6c 61 67 73 20 7c 3d 20 4c 45 56 45  w->flags |= LEVE
20920 4c 5f 46 52 45 45 4c 49 53 54 5f 4f 4e 4c 59 3b  L_FREELIST_ONLY;
20930 0a 0a 20 20 20 20 2f 2a 20 52 65 70 6c 61 63 65  ..    /* Replace
20940 20 74 68 65 20 6f 6c 64 20 6c 65 76 65 6c 73 20   the old levels 
20950 77 69 74 68 20 74 68 65 20 6e 65 77 2e 20 2a 2f  with the new. */
20960 0a 20 20 20 20 70 54 6f 70 4c 65 76 65 6c 20 3d  .    pTopLevel =
20970 20 6c 73 6d 44 62 53 6e 61 70 73 68 6f 74 4c 65   lsmDbSnapshotLe
20980 76 65 6c 28 70 44 62 2d 3e 70 57 6f 72 6b 65 72  vel(pDb->pWorker
20990 29 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 70 4e 65  );.    pNew->pNe
209a0 78 74 20 3d 20 70 3b 0a 20 20 20 20 66 6f 72 28  xt = p;.    for(
209b0 70 70 3d 26 70 54 6f 70 4c 65 76 65 6c 3b 20 2a  pp=&pTopLevel; *
209c0 70 70 21 3d 70 4c 65 76 65 6c 3b 20 70 70 3d 26  pp!=pLevel; pp=&
209d0 28 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29 29 3b  ((*pp)->pNext));
209e0 0a 20 20 20 20 2a 70 70 20 3d 20 70 4e 65 77 3b  .    *pp = pNew;
209f0 0a 20 20 20 20 6c 73 6d 44 62 53 6e 61 70 73 68  .    lsmDbSnapsh
20a00 6f 74 53 65 74 4c 65 76 65 6c 28 70 44 62 2d 3e  otSetLevel(pDb->
20a10 70 57 6f 72 6b 65 72 2c 20 70 54 6f 70 4c 65 76  pWorker, pTopLev
20a20 65 6c 29 3b 0a 0a 20 20 20 20 2f 2a 20 44 65 74  el);..    /* Det
20a30 65 72 6d 69 6e 65 20 77 68 65 74 68 65 72 20 6f  ermine whether o
20a40 72 20 6e 6f 74 20 74 68 65 20 6e 65 78 74 20 73  r not the next s
20a50 65 70 61 72 61 74 6f 72 73 20 77 69 6c 6c 20 62  eparators will b
20a60 65 20 6c 69 6e 6b 65 64 20 69 6e 20 2a 2f 0a 20  e linked in */. 
20a70 20 20 20 69 66 28 20 70 4e 65 78 74 20 26 26 20     if( pNext && 
20a80 70 4e 65 78 74 2d 3e 70 4d 65 72 67 65 3d 3d 30  pNext->pMerge==0
20a90 20 26 26 20 70 4e 65 78 74 2d 3e 6c 68 73 2e 69   && pNext->lhs.i
20aa0 52 6f 6f 74 20 26 26 20 70 4e 65 78 74 20 0a 20  Root && pNext . 
20ab0 20 20 20 20 26 26 20 28 62 46 72 65 65 4f 6e 6c      && (bFreeOnl
20ac0 79 3d 3d 30 20 7c 7c 20 28 70 4e 65 78 74 2d 3e  y==0 || (pNext->
20ad0 66 6c 61 67 73 20 26 20 4c 45 56 45 4c 5f 46 52  flags & LEVEL_FR
20ae0 45 45 4c 49 53 54 5f 4f 4e 4c 59 29 29 0a 20 20  EELIST_ONLY)).  
20af0 20 20 29 7b 0a 20 20 20 20 20 20 62 55 73 65 4e    ){.      bUseN
20b00 65 78 74 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20  ext = 1;.    }. 
20b10 20 7d 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74   }..  /* Allocat
20b20 65 20 74 68 65 20 6d 65 72 67 65 20 6f 62 6a 65  e the merge obje
20b30 63 74 20 2a 2f 0a 20 20 6e 42 79 74 65 20 3d 20  ct */.  nByte = 
20b40 73 69 7a 65 6f 66 28 4d 65 72 67 65 29 20 2b 20  sizeof(Merge) + 
20b50 73 69 7a 65 6f 66 28 4d 65 72 67 65 49 6e 70 75  sizeof(MergeInpu
20b60 74 29 20 2a 20 28 6e 4d 65 72 67 65 20 2b 20 62  t) * (nMerge + b
20b70 55 73 65 4e 65 78 74 29 3b 0a 20 20 70 4d 65 72  UseNext);.  pMer
20b80 67 65 20 3d 20 28 4d 65 72 67 65 20 2a 29 6c 73  ge = (Merge *)ls
20b90 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28 70 44  mMallocZeroRc(pD
20ba0 62 2d 3e 70 45 6e 76 2c 20 6e 42 79 74 65 2c 20  b->pEnv, nByte, 
20bb0 26 72 63 29 3b 0a 20 20 69 66 28 20 70 4d 65 72  &rc);.  if( pMer
20bc0 67 65 20 29 7b 0a 20 20 20 20 70 4d 65 72 67 65  ge ){.    pMerge
20bd0 2d 3e 61 49 6e 70 75 74 20 3d 20 28 4d 65 72 67  ->aInput = (Merg
20be0 65 49 6e 70 75 74 20 2a 29 26 70 4d 65 72 67 65  eInput *)&pMerge
20bf0 5b 31 5d 3b 0a 20 20 20 20 70 4d 65 72 67 65 2d  [1];.    pMerge-
20c00 3e 6e 49 6e 70 75 74 20 3d 20 6e 4d 65 72 67 65  >nInput = nMerge
20c10 20 2b 20 62 55 73 65 4e 65 78 74 3b 0a 20 20 20   + bUseNext;.   
20c20 20 70 4e 65 77 2d 3e 70 4d 65 72 67 65 20 3d 20   pNew->pMerge = 
20c30 70 4d 65 72 67 65 3b 0a 20 20 7d 0a 0a 20 20 2a  pMerge;.  }..  *
20c40 70 70 4e 65 77 20 3d 20 70 4e 65 77 3b 0a 20 20  ppNew = pNew;.  
20c50 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
20c60 61 74 69 63 20 69 6e 74 20 6d 65 72 67 65 57 6f  atic int mergeWo
20c70 72 6b 65 72 49 6e 69 74 28 0a 20 20 6c 73 6d 5f  rkerInit(.  lsm_
20c80 64 62 20 2a 70 44 62 2c 20 20 20 20 20 20 20 20  db *pDb,        
20c90 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
20ca0 62 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20  b connection to 
20cb0 64 6f 20 6d 65 72 67 65 20 77 6f 72 6b 20 2a 2f  do merge work */
20cc0 0a 20 20 4c 65 76 65 6c 20 2a 70 4c 65 76 65 6c  .  Level *pLevel
20cd0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
20ce0 20 20 20 2f 2a 20 4c 65 76 65 6c 20 74 6f 20 77     /* Level to w
20cf0 6f 72 6b 20 6f 6e 20 6d 65 72 67 69 6e 67 20 2a  ork on merging *
20d00 2f 0a 20 20 4d 65 72 67 65 57 6f 72 6b 65 72 20  /.  MergeWorker 
20d10 2a 70 4d 57 20 20 20 20 20 20 20 20 20 20 20 20  *pMW            
20d20 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20 74 6f      /* Object to
20d30 20 69 6e 69 74 69 61 6c 69 7a 65 20 2a 2f 0a 29   initialize */.)
20d40 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d  {.  int rc = LSM
20d50 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
20d60 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
20d70 64 65 20 2a 2f 0a 20 20 4d 65 72 67 65 20 2a 70  de */.  Merge *p
20d80 4d 65 72 67 65 20 3d 20 70 4c 65 76 65 6c 2d 3e  Merge = pLevel->
20d90 70 4d 65 72 67 65 3b 20 2f 2a 20 50 65 72 73 69  pMerge; /* Persi
20da0 73 74 65 6e 74 20 70 61 72 74 20 6f 66 20 6d 65  stent part of me
20db0 72 67 65 20 73 74 61 74 65 20 2a 2f 0a 20 20 4d  rge state */.  M
20dc0 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72  ultiCursor *pCsr
20dd0 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 2f   = 0;          /
20de0 2a 20 43 75 72 73 6f 72 20 6f 70 65 6e 65 64 20  * Cursor opened 
20df0 66 6f 72 20 70 4d 57 20 2a 2f 0a 20 20 4c 65 76  for pMW */.  Lev
20e00 65 6c 20 2a 70 4e 65 78 74 20 3d 20 70 4c 65 76  el *pNext = pLev
20e10 65 6c 2d 3e 70 4e 65 78 74 3b 20 20 20 2f 2a 20  el->pNext;   /* 
20e20 4e 65 78 74 20 6c 65 76 65 6c 20 69 6e 20 4c 53  Next level in LS
20e30 4d 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20  M */..  assert( 
20e40 70 44 62 2d 3e 70 57 6f 72 6b 65 72 20 29 3b 0a  pDb->pWorker );.
20e50 20 20 61 73 73 65 72 74 28 20 70 4c 65 76 65 6c    assert( pLevel
20e60 2d 3e 70 4d 65 72 67 65 20 29 3b 0a 20 20 61 73  ->pMerge );.  as
20e70 73 65 72 74 28 20 70 4c 65 76 65 6c 2d 3e 6e 52  sert( pLevel->nR
20e80 69 67 68 74 3e 30 20 29 3b 0a 0a 20 20 6d 65 6d  ight>0 );..  mem
20e90 73 65 74 28 70 4d 57 2c 20 30 2c 20 73 69 7a 65  set(pMW, 0, size
20ea0 6f 66 28 4d 65 72 67 65 57 6f 72 6b 65 72 29 29  of(MergeWorker))
20eb0 3b 0a 20 20 70 4d 57 2d 3e 70 44 62 20 3d 20 70  ;.  pMW->pDb = p
20ec0 44 62 3b 0a 20 20 70 4d 57 2d 3e 70 4c 65 76 65  Db;.  pMW->pLeve
20ed0 6c 20 3d 20 70 4c 65 76 65 6c 3b 0a 20 20 70 4d  l = pLevel;.  pM
20ee0 57 2d 3e 61 47 6f 62 62 6c 65 20 3d 20 6c 73 6d  W->aGobble = lsm
20ef0 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28 70 44 62  MallocZeroRc(pDb
20f00 2d 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66 28 50  ->pEnv, sizeof(P
20f10 67 6e 6f 29 20 2a 20 70 4c 65 76 65 6c 2d 3e 6e  gno) * pLevel->n
20f20 52 69 67 68 74 2c 20 26 72 63 29 3b 0a 0a 20 20  Right, &rc);..  
20f30 2f 2a 20 43 72 65 61 74 65 20 61 20 6d 75 6c 74  /* Create a mult
20f40 69 2d 63 75 72 73 6f 72 20 74 6f 20 72 65 61 64  i-cursor to read
20f50 20 74 68 65 20 64 61 74 61 20 74 6f 20 77 72 69   the data to wri
20f60 74 65 20 74 6f 20 74 68 65 20 6e 65 77 0a 20 20  te to the new.  
20f70 2a 2a 20 73 65 67 6d 65 6e 74 2e 20 54 68 65 20  ** segment. The 
20f80 6e 65 77 20 73 65 67 6d 65 6e 74 20 63 6f 6e 74  new segment cont
20f90 61 69 6e 73 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20  ains:.  **.  ** 
20fa0 20 20 31 2e 20 52 65 63 6f 72 64 73 20 66 72 6f    1. Records fro
20fb0 6d 20 4c 48 53 20 6f 66 20 65 61 63 68 20 6f 66  m LHS of each of
20fc0 20 74 68 65 20 6e 4d 65 72 67 65 20 6c 65 76 65   the nMerge leve
20fd0 6c 73 20 62 65 69 6e 67 20 6d 65 72 67 65 64 2e  ls being merged.
20fe0 0a 20 20 2a 2a 20 20 20 32 2e 20 53 65 70 61 72  .  **   2. Separ
20ff0 61 74 6f 72 73 20 66 72 6f 6d 20 65 69 74 68 65  ators from eithe
21000 72 20 74 68 65 20 6c 61 73 74 20 6c 65 76 65 6c  r the last level
21010 20 62 65 69 6e 67 20 6d 65 72 67 65 64 2c 20 6f   being merged, o
21020 72 20 74 68 65 0a 20 20 2a 2a 20 20 20 20 20 20  r the.  **      
21030 73 65 70 61 72 61 74 6f 72 73 20 61 74 74 61 63  separators attac
21040 68 65 64 20 74 6f 20 74 68 65 20 4c 48 53 20 6f  hed to the LHS o
21050 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  f the following 
21060 6c 65 76 65 6c 2c 20 6f 72 20 6e 65 69 74 68 65  level, or neithe
21070 72 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49 66 20  r..  **.  ** If 
21080 74 68 65 20 6e 65 77 20 6c 65 76 65 6c 20 69 73  the new level is
21090 20 74 68 65 20 6c 6f 77 65 73 74 20 28 6f 6c 64   the lowest (old
210a0 65 73 74 29 20 69 6e 20 74 68 65 20 64 62 2c 20  est) in the db, 
210b0 64 69 73 63 61 72 64 20 61 6e 79 0a 20 20 2a 2a  discard any.  **
210c0 20 64 65 6c 65 74 65 20 6b 65 79 73 2e 20 4b 65   delete keys. Ke
210d0 79 20 61 6e 6e 69 68 69 6c 61 74 69 6f 6e 2e 0a  y annihilation..
210e0 20 20 2a 2f 0a 20 20 70 43 73 72 20 3d 20 6d 75    */.  pCsr = mu
210f0 6c 74 69 43 75 72 73 6f 72 4e 65 77 28 70 44 62  ltiCursorNew(pDb
21100 2c 20 26 72 63 29 3b 0a 20 20 69 66 28 20 70 43  , &rc);.  if( pC
21110 73 72 20 29 7b 0a 20 20 20 20 70 43 73 72 2d 3e  sr ){.    pCsr->
21120 66 6c 61 67 73 20 7c 3d 20 43 55 52 53 4f 52 5f  flags |= CURSOR_
21130 4e 45 58 54 5f 4f 4b 3b 0a 20 20 20 20 72 63 20  NEXT_OK;.    rc 
21140 3d 20 6d 75 6c 74 69 43 75 72 73 6f 72 41 64 64  = multiCursorAdd
21150 52 68 73 28 70 43 73 72 2c 20 70 4c 65 76 65 6c  Rhs(pCsr, pLevel
21160 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d  );.  }.  if( rc=
21170 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 4d 65 72 67  =LSM_OK && pMerg
21180 65 2d 3e 6e 49 6e 70 75 74 20 3e 20 70 4c 65 76  e->nInput > pLev
21190 65 6c 2d 3e 6e 52 69 67 68 74 20 29 7b 0a 20 20  el->nRight ){.  
211a0 20 20 72 63 20 3d 20 62 74 72 65 65 43 75 72 73    rc = btreeCurs
211b0 6f 72 4e 65 77 28 70 44 62 2c 20 26 70 4e 65 78  orNew(pDb, &pNex
211c0 74 2d 3e 6c 68 73 2c 20 26 70 43 73 72 2d 3e 70  t->lhs, &pCsr->p
211d0 42 74 43 73 72 29 3b 0a 20 20 7d 65 6c 73 65 20  BtCsr);.  }else 
211e0 69 66 28 20 70 4e 65 78 74 20 29 7b 0a 20 20 20  if( pNext ){.   
211f0 20 6d 75 6c 74 69 43 75 72 73 6f 72 52 65 61 64   multiCursorRead
21200 53 65 70 61 72 61 74 6f 72 73 28 70 43 73 72 29  Separators(pCsr)
21210 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 6d  ;.  }else{.    m
21220 75 6c 74 69 43 75 72 73 6f 72 49 67 6e 6f 72 65  ultiCursorIgnore
21230 44 65 6c 65 74 65 28 70 43 73 72 29 3b 0a 20 20  Delete(pCsr);.  
21240 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 72 63 21  }..  assert( rc!
21250 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 70 4d 65 72 67  =LSM_OK || pMerg
21260 65 2d 3e 6e 49 6e 70 75 74 3d 3d 28 70 43 73 72  e->nInput==(pCsr
21270 2d 3e 6e 50 74 72 2b 28 70 43 73 72 2d 3e 70 42  ->nPtr+(pCsr->pB
21280 74 43 73 72 21 3d 30 29 29 20 29 3b 0a 20 20 70  tCsr!=0)) );.  p
21290 4d 57 2d 3e 70 43 73 72 20 3d 20 70 43 73 72 3b  MW->pCsr = pCsr;
212a0 0a 0a 20 20 2f 2a 20 4c 6f 61 64 20 74 68 65 20  ..  /* Load the 
212b0 62 2d 74 72 65 65 20 68 69 65 72 61 72 63 68 79  b-tree hierarchy
212c0 20 69 6e 74 6f 20 6d 65 6d 6f 72 79 2e 20 2a 2f   into memory. */
212d0 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f  .  if( rc==LSM_O
212e0 4b 20 29 20 72 63 20 3d 20 6d 65 72 67 65 57 6f  K ) rc = mergeWo
212f0 72 6b 65 72 4c 6f 61 64 48 69 65 72 61 72 63 68  rkerLoadHierarch
21300 79 28 70 4d 57 29 3b 0a 20 20 69 66 28 20 72 63  y(pMW);.  if( rc
21310 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 4d 57 2d  ==LSM_OK && pMW-
21320 3e 68 69 65 72 2e 6e 48 69 65 72 3d 3d 30 20 29  >hier.nHier==0 )
21330 7b 0a 20 20 20 20 70 4d 57 2d 3e 61 53 61 76 65  {.    pMW->aSave
21340 5b 30 5d 2e 69 50 67 6e 6f 20 3d 20 70 4c 65 76  [0].iPgno = pLev
21350 65 6c 2d 3e 6c 68 73 2e 69 46 69 72 73 74 3b 0a  el->lhs.iFirst;.
21360 20 20 7d 0a 0a 20 20 2f 2a 20 50 6f 73 69 74 69    }..  /* Positi
21370 6f 6e 20 74 68 65 20 63 75 72 73 6f 72 2e 20 2a  on the cursor. *
21380 2f 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f  /.  if( rc==LSM_
21390 4f 4b 20 29 7b 0a 20 20 20 20 70 43 73 72 2d 3e  OK ){.    pCsr->
213a0 70 50 72 65 76 4d 65 72 67 65 50 74 72 20 3d 20  pPrevMergePtr = 
213b0 26 70 4d 65 72 67 65 2d 3e 69 43 75 72 72 65 6e  &pMerge->iCurren
213c0 74 50 74 72 3b 0a 20 20 20 20 69 66 28 20 70 4c  tPtr;.    if( pL
213d0 65 76 65 6c 2d 3e 6c 68 73 2e 69 46 69 72 73 74  evel->lhs.iFirst
213e0 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  ==0 ){.      /* 
213f0 54 68 65 20 6f 75 74 70 75 74 20 61 72 72 61 79  The output array
21400 20 69 73 20 73 74 69 6c 6c 20 65 6d 70 74 79 2e   is still empty.
21410 20 53 6f 20 70 6f 73 69 74 69 6f 6e 20 74 68 65   So position the
21420 20 63 75 72 73 6f 72 20 61 74 20 74 68 65 20 76   cursor at the v
21430 65 72 79 20 0a 20 20 20 20 20 20 2a 2a 20 73 74  ery .      ** st
21440 61 72 74 20 6f 66 20 74 68 65 20 69 6e 70 75 74  art of the input
21450 2e 20 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d  .  */.      rc =
21460 20 6d 75 6c 74 69 43 75 72 73 6f 72 45 6e 64 28   multiCursorEnd(
21470 70 43 73 72 2c 20 30 29 3b 0a 20 20 20 20 7d 65  pCsr, 0);.    }e
21480 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20 54 68  lse{.      /* Th
21490 65 20 6f 75 74 70 75 74 20 61 72 72 61 79 20 69  e output array i
214a0 73 20 6e 6f 6e 2d 65 6d 70 74 79 2e 20 50 6f 73  s non-empty. Pos
214b0 69 74 69 6f 6e 20 74 68 65 20 63 75 72 73 6f 72  ition the cursor
214c0 20 62 61 73 65 64 20 6f 6e 20 74 68 65 0a 20 20   based on the.  
214d0 20 20 20 20 2a 2a 20 70 61 67 65 2f 63 65 6c 6c      ** page/cell
214e0 20 64 61 74 61 20 73 61 76 65 64 20 69 6e 20 74   data saved in t
214f0 68 65 20 4d 65 72 67 65 2e 61 49 6e 70 75 74 5b  he Merge.aInput[
21500 5d 20 61 72 72 61 79 2e 20 20 2a 2f 0a 20 20 20  ] array.  */.   
21510 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20     int i;.      
21520 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 4c 53 4d  for(i=0; rc==LSM
21530 5f 4f 4b 20 26 26 20 69 3c 70 43 73 72 2d 3e 6e  _OK && i<pCsr->n
21540 50 74 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  Ptr; i++){.     
21550 20 20 20 4d 65 72 67 65 49 6e 70 75 74 20 2a 70     MergeInput *p
21560 49 6e 70 75 74 20 3d 20 26 70 4d 65 72 67 65 2d  Input = &pMerge-
21570 3e 61 49 6e 70 75 74 5b 69 5d 3b 0a 20 20 20 20  >aInput[i];.    
21580 20 20 20 20 69 66 28 20 70 49 6e 70 75 74 2d 3e      if( pInput->
21590 69 50 67 20 29 7b 0a 20 20 20 20 20 20 20 20 20  iPg ){.         
215a0 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74   SegmentPtr *pPt
215b0 72 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73  r;.          ass
215c0 65 72 74 28 20 70 43 73 72 2d 3e 61 50 74 72 5b  ert( pCsr->aPtr[
215d0 69 5d 2e 70 50 67 3d 3d 30 20 29 3b 0a 20 20 20  i].pPg==0 );.   
215e0 20 20 20 20 20 20 20 70 50 74 72 20 3d 20 26 70         pPtr = &p
215f0 43 73 72 2d 3e 61 50 74 72 5b 69 5d 3b 0a 20 20  Csr->aPtr[i];.  
21600 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65 67          rc = seg
21610 6d 65 6e 74 50 74 72 4c 6f 61 64 50 61 67 65 28  mentPtrLoadPage(
21620 70 44 62 2d 3e 70 46 53 2c 20 70 50 74 72 2c 20  pDb->pFS, pPtr, 
21630 70 49 6e 70 75 74 2d 3e 69 50 67 29 3b 0a 20 20  pInput->iPg);.  
21640 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d          if( rc==
21650 4c 53 4d 5f 4f 4b 20 26 26 20 70 50 74 72 2d 3e  LSM_OK && pPtr->
21660 6e 43 65 6c 6c 3e 30 20 29 7b 0a 20 20 20 20 20  nCell>0 ){.     
21670 20 20 20 20 20 20 20 72 63 20 3d 20 73 65 67 6d         rc = segm
21680 65 6e 74 50 74 72 4c 6f 61 64 43 65 6c 6c 28 70  entPtrLoadCell(p
21690 50 74 72 2c 20 70 49 6e 70 75 74 2d 3e 69 43 65  Ptr, pInput->iCe
216a0 6c 6c 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  ll);.          }
216b0 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
216c0 20 7d 0a 0a 20 20 20 20 20 20 69 66 28 20 72 63   }..      if( rc
216d0 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 43 73 72  ==LSM_OK && pCsr
216e0 2d 3e 70 42 74 43 73 72 20 29 7b 0a 20 20 20 20  ->pBtCsr ){.    
216f0 20 20 20 20 69 6e 74 20 28 2a 78 43 6d 70 29 28      int (*xCmp)(
21700 76 6f 69 64 20 2a 2c 20 69 6e 74 2c 20 76 6f 69  void *, int, voi
21710 64 20 2a 2c 20 69 6e 74 29 20 3d 20 70 43 73 72  d *, int) = pCsr
21720 2d 3e 70 44 62 2d 3e 78 43 6d 70 3b 0a 20 20 20  ->pDb->xCmp;.   
21730 20 20 20 20 20 61 73 73 65 72 74 28 20 69 3d 3d       assert( i==
21740 70 43 73 72 2d 3e 6e 50 74 72 20 29 3b 0a 20 20  pCsr->nPtr );.  
21750 20 20 20 20 20 20 72 63 20 3d 20 62 74 72 65 65        rc = btree
21760 43 75 72 73 6f 72 52 65 73 74 6f 72 65 28 70 43  CursorRestore(pC
21770 73 72 2d 3e 70 42 74 43 73 72 2c 20 78 43 6d 70  sr->pBtCsr, xCmp
21780 2c 20 26 70 4d 65 72 67 65 2d 3e 61 49 6e 70 75  , &pMerge->aInpu
21790 74 5b 69 5d 29 3b 0a 20 20 20 20 20 20 7d 0a 0a  t[i]);.      }..
217a0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53        if( rc==LS
217b0 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  M_OK ){.        
217c0 72 63 20 3d 20 6d 75 6c 74 69 43 75 72 73 6f 72  rc = multiCursor
217d0 53 65 74 75 70 54 72 65 65 28 70 43 73 72 2c 20  SetupTree(pCsr, 
217e0 30 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  0);.      }.    
217f0 7d 0a 20 20 20 20 70 43 73 72 2d 3e 66 6c 61 67  }.    pCsr->flag
21800 73 20 7c 3d 20 43 55 52 53 4f 52 5f 4e 45 58 54  s |= CURSOR_NEXT
21810 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  _OK;.  }..  retu
21820 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
21830 20 69 6e 74 20 73 6f 72 74 65 64 42 74 72 65 65   int sortedBtree
21840 47 6f 62 62 6c 65 28 0a 20 20 6c 73 6d 5f 64 62  Gobble(.  lsm_db
21850 20 2a 70 44 62 2c 20 20 20 20 20 20 20 20 20 20   *pDb,          
21860 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 6f 72            /* Wor
21870 6b 65 72 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a  ker connection *
21880 2f 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  /.  MultiCursor 
21890 2a 70 43 73 72 2c 20 20 20 20 20 20 20 20 20 20  *pCsr,          
218a0 20 20 20 20 2f 2a 20 4d 75 6c 74 69 2d 63 75 72      /* Multi-cur
218b0 73 6f 72 20 62 65 69 6e 67 20 75 73 65 64 20 66  sor being used f
218c0 6f 72 20 61 20 6d 65 72 67 65 20 2a 2f 0a 20 20  or a merge */.  
218d0 69 6e 74 20 69 47 6f 62 62 6c 65 20 20 20 20 20  int iGobble     
218e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
218f0 2f 2a 20 70 43 73 72 2d 3e 61 50 74 72 5b 5d 20  /* pCsr->aPtr[] 
21900 65 6e 74 72 79 20 74 6f 20 6f 70 65 72 61 74 65  entry to operate
21910 20 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20   on */.){.  int 
21920 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 69  rc = LSM_OK;.  i
21930 66 28 20 72 74 54 6f 70 69 63 28 70 43 73 72 2d  f( rtTopic(pCsr-
21940 3e 65 54 79 70 65 29 3d 3d 30 20 29 7b 0a 20 20  >eType)==0 ){.  
21950 20 20 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 20    Segment *pSeg 
21960 3d 20 70 43 73 72 2d 3e 61 50 74 72 5b 69 47 6f  = pCsr->aPtr[iGo
21970 62 62 6c 65 5d 2e 70 53 65 67 3b 0a 20 20 20 20  bble].pSeg;.    
21980 50 67 6e 6f 20 2a 61 50 67 3b 0a 20 20 20 20 69  Pgno *aPg;.    i
21990 6e 74 20 6e 50 67 3b 0a 0a 20 20 20 20 2f 2a 20  nt nPg;..    /* 
219a0 53 65 65 6b 20 66 72 6f 6d 20 74 68 65 20 72 6f  Seek from the ro
219b0 6f 74 20 6f 66 20 74 68 65 20 62 2d 74 72 65 65  ot of the b-tree
219c0 20 74 6f 20 74 68 65 20 73 65 67 6d 65 6e 74 20   to the segment 
219d0 6c 65 61 66 20 74 68 61 74 20 6d 61 79 20 63 6f  leaf that may co
219e0 6e 74 61 69 6e 0a 20 20 20 20 2a 2a 20 61 20 6b  ntain.    ** a k
219f0 65 79 20 65 71 75 61 6c 20 74 6f 20 74 68 65 20  ey equal to the 
21a00 6f 6e 65 20 6d 75 6c 74 69 2d 63 75 72 73 6f 72  one multi-cursor
21a10 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74   currently point
21a20 73 20 74 6f 2e 20 52 65 63 6f 72 64 20 74 68 65  s to. Record the
21a30 0a 20 20 20 20 2a 2a 20 70 61 67 65 20 6e 75 6d  .    ** page num
21a40 62 65 72 20 6f 66 20 65 61 63 68 20 62 2d 74 72  ber of each b-tr
21a50 65 65 20 70 61 67 65 20 61 6e 64 20 74 68 65 20  ee page and the 
21a60 6c 65 61 66 2e 20 54 68 65 20 73 65 67 6d 65 6e  leaf. The segmen
21a70 74 20 6d 61 79 20 62 65 0a 20 20 20 20 2a 2a 20  t may be.    ** 
21a80 67 6f 62 62 6c 65 64 20 75 70 20 74 6f 20 28 62  gobbled up to (b
21a90 75 74 20 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67  ut not including
21aa0 29 20 74 68 65 20 66 69 72 73 74 20 6f 66 20 74  ) the first of t
21ab0 68 65 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72  hese page number
21ac0 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 61 73  s..    */.    as
21ad0 73 65 72 74 28 20 70 53 65 67 2d 3e 69 52 6f 6f  sert( pSeg->iRoo
21ae0 74 3e 30 20 29 3b 0a 20 20 20 20 61 50 67 20 3d  t>0 );.    aPg =
21af0 20 6c 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63   lsmMallocZeroRc
21b00 28 70 44 62 2d 3e 70 45 6e 76 2c 20 73 69 7a 65  (pDb->pEnv, size
21b10 6f 66 28 50 67 6e 6f 29 2a 33 32 2c 20 26 72 63  of(Pgno)*32, &rc
21b20 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  );.    if( rc==L
21b30 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  SM_OK ){.      r
21b40 63 20 3d 20 73 65 65 6b 49 6e 42 74 72 65 65 28  c = seekInBtree(
21b50 70 43 73 72 2c 20 70 53 65 67 2c 20 0a 20 20 20  pCsr, pSeg, .   
21b60 20 20 20 20 20 20 20 72 74 54 6f 70 69 63 28 70         rtTopic(p
21b70 43 73 72 2d 3e 65 54 79 70 65 29 2c 20 70 43 73  Csr->eType), pCs
21b80 72 2d 3e 6b 65 79 2e 70 44 61 74 61 2c 20 70 43  r->key.pData, pC
21b90 73 72 2d 3e 6b 65 79 2e 6e 44 61 74 61 2c 20 61  sr->key.nData, a
21ba0 50 67 2c 20 30 0a 20 20 20 20 20 20 29 3b 20 0a  Pg, 0.      ); .
21bb0 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72      }..    if( r
21bc0 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
21bd0 20 20 20 66 6f 72 28 6e 50 67 3d 30 3b 20 61 50     for(nPg=0; aP
21be0 67 5b 6e 50 67 5d 3b 20 6e 50 67 2b 2b 29 3b 0a  g[nPg]; nPg++);.
21bf0 20 20 20 20 20 20 6c 73 6d 46 73 47 6f 62 62 6c        lsmFsGobbl
21c00 65 28 70 44 62 2c 20 70 53 65 67 2c 20 61 50 67  e(pDb, pSeg, aPg
21c10 2c 20 6e 50 67 29 3b 0a 20 20 20 20 7d 0a 0a 20  , nPg);.    }.. 
21c20 20 20 20 6c 73 6d 46 72 65 65 28 70 44 62 2d 3e     lsmFree(pDb->
21c30 70 45 6e 76 2c 20 61 50 67 29 3b 0a 20 20 7d 0a  pEnv, aPg);.  }.
21c40 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
21c50 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 70  /*.** Argument p
21c60 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 6c 65 76   points to a lev
21c70 65 6c 20 6f 66 20 61 67 65 20 4e 2e 20 52 65 74  el of age N. Ret
21c80 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  urn the number o
21c90 66 20 6c 65 76 65 6c 73 20 69 6e 0a 2a 2a 20 74  f levels in.** t
21ca0 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 73  he linked list s
21cb0 74 61 72 74 69 6e 67 20 61 74 20 70 20 74 68 61  tarting at p tha
21cc0 74 20 68 61 76 65 20 61 67 65 3d 4e 20 28 61 6c  t have age=N (al
21cd0 77 61 79 73 20 61 74 20 6c 65 61 73 74 20 31 29  ways at least 1)
21ce0 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
21cf0 73 6f 72 74 65 64 43 6f 75 6e 74 4c 65 76 65 6c  sortedCountLevel
21d00 73 28 4c 65 76 65 6c 20 2a 70 29 7b 0a 20 20 69  s(Level *p){.  i
21d10 6e 74 20 69 41 67 65 20 3d 20 70 2d 3e 69 41 67  nt iAge = p->iAg
21d20 65 3b 0a 20 20 69 6e 74 20 6e 52 65 74 20 3d 20  e;.  int nRet = 
21d30 30 3b 0a 20 20 64 6f 20 7b 0a 20 20 20 20 6e 52  0;.  do {.    nR
21d40 65 74 2b 2b 3b 0a 20 20 20 20 70 20 3d 20 70 2d  et++;.    p = p-
21d50 3e 70 4e 65 78 74 3b 0a 20 20 7d 77 68 69 6c 65  >pNext;.  }while
21d60 28 20 70 20 26 26 20 70 2d 3e 69 41 67 65 3d 3d  ( p && p->iAge==
21d70 69 41 67 65 20 29 3b 0a 20 20 72 65 74 75 72 6e  iAge );.  return
21d80 20 6e 52 65 74 3b 0a 7d 0a 0a 73 74 61 74 69 63   nRet;.}..static
21d90 20 69 6e 74 20 73 6f 72 74 65 64 53 65 6c 65 63   int sortedSelec
21da0 74 4c 65 76 65 6c 28 6c 73 6d 5f 64 62 20 2a 70  tLevel(lsm_db *p
21db0 44 62 2c 20 69 6e 74 20 6e 4d 65 72 67 65 2c 20  Db, int nMerge, 
21dc0 4c 65 76 65 6c 20 2a 2a 70 70 4f 75 74 29 7b 0a  Level **ppOut){.
21dd0 20 20 4c 65 76 65 6c 20 2a 70 54 6f 70 4c 65 76    Level *pTopLev
21de0 65 6c 20 3d 20 6c 73 6d 44 62 53 6e 61 70 73 68  el = lsmDbSnapsh
21df0 6f 74 4c 65 76 65 6c 28 70 44 62 2d 3e 70 57 6f  otLevel(pDb->pWo
21e00 72 6b 65 72 29 3b 0a 20 20 69 6e 74 20 72 63 20  rker);.  int rc 
21e10 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 4c 65 76 65  = LSM_OK;.  Leve
21e20 6c 20 2a 70 4c 65 76 65 6c 20 3d 20 30 3b 20 20  l *pLevel = 0;  
21e30 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 75 74            /* Out
21e40 70 75 74 20 76 61 6c 75 65 20 2a 2f 0a 20 20 4c  put value */.  L
21e50 65 76 65 6c 20 2a 70 42 65 73 74 20 3d 20 30 3b  evel *pBest = 0;
21e60 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
21e70 42 65 73 74 20 6c 65 76 65 6c 20 74 6f 20 77 6f  Best level to wo
21e80 72 6b 20 6f 6e 20 66 6f 75 6e 64 20 73 6f 20 66  rk on found so f
21e90 61 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 65 73  ar */.  int nBes
21ea0 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
21eb0 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
21ec0 6f 66 20 73 65 67 6d 65 6e 74 73 20 6d 65 72 67  of segments merg
21ed0 65 64 20 61 74 20 70 42 65 73 74 20 2a 2f 0a 20  ed at pBest */. 
21ee0 20 4c 65 76 65 6c 20 2a 70 54 68 69 73 20 3d 20   Level *pThis = 
21ef0 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  0;             /
21f00 2a 20 46 69 72 73 74 20 69 6e 20 72 75 6e 20 6f  * First in run o
21f10 66 20 6c 65 76 65 6c 73 20 77 69 74 68 20 61 67  f levels with ag
21f20 65 3d 69 41 67 65 20 2a 2f 0a 20 20 69 6e 74 20  e=iAge */.  int 
21f30 6e 54 68 69 73 20 3d 20 30 3b 20 20 20 20 20 20  nThis = 0;      
21f40 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
21f50 62 65 72 20 6f 66 20 6c 65 76 65 6c 73 20 73 74  ber of levels st
21f60 61 72 74 69 6e 67 20 61 74 20 70 54 68 69 73 20  arting at pThis 
21f70 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 4d  */..  assert( nM
21f80 65 72 67 65 3e 3d 31 20 29 3b 0a 20 20 6e 42 65  erge>=1 );.  nBe
21f90 73 74 20 3d 20 4c 53 4d 5f 4d 41 58 28 31 2c 20  st = LSM_MAX(1, 
21fa0 6e 4d 65 72 67 65 2d 31 29 3b 0a 0a 20 20 2f 2a  nMerge-1);..  /*
21fb0 20 46 69 6e 64 20 74 68 65 20 6c 6f 6e 67 65 73   Find the longes
21fc0 74 20 63 6f 6e 74 69 67 75 6f 75 73 20 72 75 6e  t contiguous run
21fd0 20 6f 66 20 6c 65 76 65 6c 73 20 6e 6f 74 20 63   of levels not c
21fe0 75 72 72 65 6e 74 6c 79 20 75 6e 64 65 72 67 6f  urrently undergo
21ff0 69 6e 67 20 61 20 0a 20 20 2a 2a 20 6d 65 72 67  ing a .  ** merg
22000 65 20 77 69 74 68 20 74 68 65 20 73 61 6d 65 20  e with the same 
22010 61 67 65 20 69 6e 20 74 68 65 20 73 74 72 75 63  age in the struc
22020 74 75 72 65 2e 20 4f 72 20 74 68 65 20 6c 65 76  ture. Or the lev
22030 65 6c 20 62 65 69 6e 67 20 6d 65 72 67 65 64 0a  el being merged.
22040 20 20 2a 2a 20 77 69 74 68 20 74 68 65 20 6c 61    ** with the la
22050 72 67 65 73 74 20 6e 75 6d 62 65 72 20 6f 66 20  rgest number of 
22060 72 69 67 68 74 2d 68 61 6e 64 20 73 65 67 6d 65  right-hand segme
22070 6e 74 73 2e 20 57 6f 72 6b 20 6f 6e 20 69 74 2e  nts. Work on it.
22080 20 2a 2f 0a 20 20 66 6f 72 28 70 4c 65 76 65 6c   */.  for(pLevel
22090 3d 70 54 6f 70 4c 65 76 65 6c 3b 20 70 4c 65 76  =pTopLevel; pLev
220a0 65 6c 3b 20 70 4c 65 76 65 6c 3d 70 4c 65 76 65  el; pLevel=pLeve
220b0 6c 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 69  l->pNext){.    i
220c0 66 28 20 70 4c 65 76 65 6c 2d 3e 6e 52 69 67 68  f( pLevel->nRigh
220d0 74 3d 3d 30 20 26 26 20 70 54 68 69 73 20 26 26  t==0 && pThis &&
220e0 20 70 4c 65 76 65 6c 2d 3e 69 41 67 65 3d 3d 70   pLevel->iAge==p
220f0 54 68 69 73 2d 3e 69 41 67 65 20 29 7b 0a 20 20  This->iAge ){.  
22100 20 20 20 20 6e 54 68 69 73 2b 2b 3b 0a 20 20 20      nThis++;.   
22110 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66   }else{.      if
22120 28 20 6e 54 68 69 73 3e 6e 42 65 73 74 20 29 7b  ( nThis>nBest ){
22130 0a 20 20 20 20 20 20 20 20 69 66 28 20 28 70 4c  .        if( (pL
22140 65 76 65 6c 2d 3e 69 41 67 65 21 3d 70 54 68 69  evel->iAge!=pThi
22150 73 2d 3e 69 41 67 65 2b 31 29 0a 20 20 20 20 20  s->iAge+1).     
22160 20 20 20 20 7c 7c 20 28 70 4c 65 76 65 6c 2d 3e      || (pLevel->
22170 6e 52 69 67 68 74 3d 3d 30 20 26 26 20 73 6f 72  nRight==0 && sor
22180 74 65 64 43 6f 75 6e 74 4c 65 76 65 6c 73 28 70  tedCountLevels(p
22190 4c 65 76 65 6c 29 3c 3d 70 44 62 2d 3e 6e 4d 65  Level)<=pDb->nMe
221a0 72 67 65 29 0a 20 20 20 20 20 20 20 20 29 7b 0a  rge).        ){.
221b0 20 20 20 20 20 20 20 20 20 20 70 42 65 73 74 20            pBest 
221c0 3d 20 70 54 68 69 73 3b 0a 20 20 20 20 20 20 20  = pThis;.       
221d0 20 20 20 6e 42 65 73 74 20 3d 20 6e 54 68 69 73     nBest = nThis
221e0 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
221f0 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 70 4c    }.      if( pL
22200 65 76 65 6c 2d 3e 6e 52 69 67 68 74 20 29 7b 0a  evel->nRight ){.
22210 20 20 20 20 20 20 20 20 69 66 28 20 70 4c 65 76          if( pLev
22220 65 6c 2d 3e 6e 52 69 67 68 74 3e 6e 42 65 73 74  el->nRight>nBest
22230 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6e 42   ){.          nB
22240 65 73 74 20 3d 20 70 4c 65 76 65 6c 2d 3e 6e 52  est = pLevel->nR
22250 69 67 68 74 3b 0a 20 20 20 20 20 20 20 20 20 20  ight;.          
22260 70 42 65 73 74 20 3d 20 70 4c 65 76 65 6c 3b 0a  pBest = pLevel;.
22270 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
22280 20 20 6e 54 68 69 73 20 3d 20 30 3b 0a 20 20 20    nThis = 0;.   
22290 20 20 20 20 20 70 54 68 69 73 20 3d 20 30 3b 0a       pThis = 0;.
222a0 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
222b0 20 20 20 20 20 70 54 68 69 73 20 3d 20 70 4c 65       pThis = pLe
222c0 76 65 6c 3b 0a 20 20 20 20 20 20 20 20 6e 54 68  vel;.        nTh
222d0 69 73 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a  is = 1;.      }.
222e0 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20      }.  }.  if( 
222f0 6e 54 68 69 73 3e 6e 42 65 73 74 20 29 7b 0a 20  nThis>nBest ){. 
22300 20 20 20 61 73 73 65 72 74 28 20 70 54 68 69 73     assert( pThis
22310 20 29 3b 0a 20 20 20 20 70 42 65 73 74 20 3d 20   );.    pBest = 
22320 70 54 68 69 73 3b 0a 20 20 20 20 6e 42 65 73 74  pThis;.    nBest
22330 20 3d 20 6e 54 68 69 73 3b 0a 20 20 7d 0a 0a 20   = nThis;.  }.. 
22340 20 69 66 28 20 70 42 65 73 74 3d 3d 30 20 26 26   if( pBest==0 &&
22350 20 6e 4d 65 72 67 65 3d 3d 31 20 29 7b 0a 20 20   nMerge==1 ){.  
22360 20 20 69 6e 74 20 6e 46 72 65 65 20 3d 20 30 3b    int nFree = 0;
22370 0a 20 20 20 20 69 6e 74 20 6e 55 73 72 20 3d 20  .    int nUsr = 
22380 30 3b 0a 20 20 20 20 66 6f 72 28 70 4c 65 76 65  0;.    for(pLeve
22390 6c 3d 70 54 6f 70 4c 65 76 65 6c 3b 20 70 4c 65  l=pTopLevel; pLe
223a0 76 65 6c 3b 20 70 4c 65 76 65 6c 3d 70 4c 65 76  vel; pLevel=pLev
223b0 65 6c 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  el->pNext){.    
223c0 20 20 61 73 73 65 72 74 28 20 21 70 4c 65 76 65    assert( !pLeve
223d0 6c 2d 3e 6e 52 69 67 68 74 20 29 3b 0a 20 20 20  l->nRight );.   
223e0 20 20 20 69 66 28 20 70 4c 65 76 65 6c 2d 3e 66     if( pLevel->f
223f0 6c 61 67 73 20 26 20 4c 45 56 45 4c 5f 46 52 45  lags & LEVEL_FRE
22400 45 4c 49 53 54 5f 4f 4e 4c 59 20 29 7b 0a 20 20  ELIST_ONLY ){.  
22410 20 20 20 20 20 20 6e 46 72 65 65 2b 2b 3b 0a 20        nFree++;. 
22420 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
22430 20 20 20 20 6e 55 73 72 2b 2b 3b 0a 20 20 20 20      nUsr++;.    
22440 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
22450 28 20 6e 55 73 72 3e 31 20 29 7b 0a 20 20 20 20  ( nUsr>1 ){.    
22460 20 20 70 42 65 73 74 20 3d 20 70 54 6f 70 4c 65    pBest = pTopLe
22470 76 65 6c 3b 0a 20 20 20 20 20 20 6e 42 65 73 74  vel;.      nBest
22480 20 3d 20 6e 46 72 65 65 20 2b 20 6e 55 73 72 3b   = nFree + nUsr;
22490 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
224a0 28 20 70 42 65 73 74 20 29 7b 0a 20 20 20 20 69  ( pBest ){.    i
224b0 66 28 20 70 42 65 73 74 2d 3e 6e 52 69 67 68 74  f( pBest->nRight
224c0 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20  ==0 ){.      rc 
224d0 3d 20 73 6f 72 74 65 64 4d 65 72 67 65 53 65 74  = sortedMergeSet
224e0 75 70 28 70 44 62 2c 20 70 42 65 73 74 2c 20 6e  up(pDb, pBest, n
224f0 42 65 73 74 2c 20 70 70 4f 75 74 29 3b 0a 20 20  Best, ppOut);.  
22500 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a    }else{.      *
22510 70 70 4f 75 74 20 3d 20 70 42 65 73 74 3b 0a 20  ppOut = pBest;. 
22520 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
22530 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
22540 20 69 6e 74 20 73 6f 72 74 65 64 44 62 49 73 46   int sortedDbIsF
22550 75 6c 6c 28 6c 73 6d 5f 64 62 20 2a 70 44 62 29  ull(lsm_db *pDb)
22560 7b 0a 20 20 4c 65 76 65 6c 20 2a 70 54 6f 70 20  {.  Level *pTop 
22570 3d 20 6c 73 6d 44 62 53 6e 61 70 73 68 6f 74 4c  = lsmDbSnapshotL
22580 65 76 65 6c 28 70 44 62 2d 3e 70 57 6f 72 6b 65  evel(pDb->pWorke
22590 72 29 3b 0a 0a 20 20 69 66 28 20 6c 73 6d 44 61  r);..  if( lsmDa
225a0 74 61 62 61 73 65 46 75 6c 6c 28 70 44 62 29 20  tabaseFull(pDb) 
225b0 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 69 66  ) return 1;.  if
225c0 28 20 70 54 6f 70 20 26 26 20 70 54 6f 70 2d 3e  ( pTop && pTop->
225d0 69 41 67 65 3d 3d 30 0a 20 20 20 26 26 20 28 70  iAge==0.   && (p
225e0 54 6f 70 2d 3e 6e 52 69 67 68 74 20 7c 7c 20 73  Top->nRight || s
225f0 6f 72 74 65 64 43 6f 75 6e 74 4c 65 76 65 6c 73  ortedCountLevels
22600 28 70 54 6f 70 29 3e 3d 70 44 62 2d 3e 6e 4d 65  (pTop)>=pDb->nMe
22610 72 67 65 29 0a 20 20 29 7b 0a 20 20 20 20 72 65  rge).  ){.    re
22620 74 75 72 6e 20 31 3b 0a 20 20 7d 0a 20 20 72 65  turn 1;.  }.  re
22630 74 75 72 6e 20 30 3b 0a 7d 0a 0a 74 79 70 65 64  turn 0;.}..typed
22640 65 66 20 73 74 72 75 63 74 20 4d 6f 76 65 42 6c  ef struct MoveBl
22650 6f 63 6b 43 74 78 20 4d 6f 76 65 42 6c 6f 63 6b  ockCtx MoveBlock
22660 43 74 78 3b 0a 73 74 72 75 63 74 20 4d 6f 76 65  Ctx;.struct Move
22670 42 6c 6f 63 6b 43 74 78 20 7b 0a 20 20 69 6e 74  BlockCtx {.  int
22680 20 69 53 65 65 6e 3b 20 20 20 20 20 20 20 20 20   iSeen;         
22690 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
226a0 50 72 65 76 69 6f 75 73 20 66 72 65 65 20 62 6c  Previous free bl
226b0 6f 63 6b 20 6f 6e 20 6c 69 73 74 20 2a 2f 0a 20  ock on list */. 
226c0 20 69 6e 74 20 69 46 72 6f 6d 3b 20 20 20 20 20   int iFrom;     
226d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
226e0 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72   /* Total number
226f0 20 6f 66 20 62 6c 6f 63 6b 73 20 69 6e 20 66 69   of blocks in fi
22700 6c 65 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74 69 63  le */.};..static
22710 20 69 6e 74 20 6d 6f 76 65 42 6c 6f 63 6b 43 62   int moveBlockCb
22720 28 76 6f 69 64 20 2a 70 43 74 78 2c 20 69 6e 74  (void *pCtx, int
22730 20 69 42 6c 6b 2c 20 69 36 34 20 69 53 6e 61 70   iBlk, i64 iSnap
22740 73 68 6f 74 29 7b 0a 20 20 4d 6f 76 65 42 6c 6f  shot){.  MoveBlo
22750 63 6b 43 74 78 20 2a 70 20 3d 20 28 4d 6f 76 65  ckCtx *p = (Move
22760 42 6c 6f 63 6b 43 74 78 20 2a 29 70 43 74 78 3b  BlockCtx *)pCtx;
22770 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 69 46  .  assert( p->iF
22780 72 6f 6d 3d 3d 30 20 29 3b 0a 20 20 69 66 28 20  rom==0 );.  if( 
22790 69 42 6c 6b 3d 3d 28 70 2d 3e 69 53 65 65 6e 2d  iBlk==(p->iSeen-
227a0 31 29 20 29 7b 0a 20 20 20 20 70 2d 3e 69 53 65  1) ){.    p->iSe
227b0 65 6e 20 3d 20 69 42 6c 6b 3b 0a 20 20 20 20 72  en = iBlk;.    r
227c0 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 70  eturn 0;.  }.  p
227d0 2d 3e 69 46 72 6f 6d 20 3d 20 70 2d 3e 69 53 65  ->iFrom = p->iSe
227e0 65 6e 2d 31 3b 0a 20 20 72 65 74 75 72 6e 20 31  en-1;.  return 1
227f0 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
22800 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
22810 65 64 20 74 6f 20 66 75 72 74 68 65 72 20 63 6f  ed to further co
22820 6d 70 61 63 74 20 61 20 64 61 74 61 62 61 73 65  mpact a database
22830 20 66 6f 72 20 77 68 69 63 68 20 61 6c 6c 20 0a   for which all .
22840 2a 2a 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e  ** of the conten
22850 74 20 68 61 73 20 61 6c 72 65 61 64 79 20 62 65  t has already be
22860 65 6e 20 6d 65 72 67 65 64 20 69 6e 74 6f 20 61  en merged into a
22870 20 73 69 6e 67 6c 65 20 73 65 67 6d 65 6e 74 2e   single segment.
22880 20 49 66 20 0a 2a 2a 20 70 6f 73 73 69 62 6c 65   If .** possible
22890 2c 20 69 74 20 6d 6f 76 65 73 20 74 68 65 20 63  , it moves the c
228a0 6f 6e 74 65 6e 74 73 20 6f 66 20 61 20 73 69 6e  ontents of a sin
228b0 67 6c 65 20 62 6c 6f 63 6b 20 66 72 6f 6d 20 74  gle block from t
228c0 68 65 20 65 6e 64 20 6f 66 20 74 68 65 0a 2a 2a  he end of the.**
228d0 20 66 69 6c 65 20 74 6f 20 61 20 66 72 65 65 2d   file to a free-
228e0 62 6c 6f 63 6b 20 74 68 61 74 20 6c 69 65 73 20  block that lies 
228f0 63 6c 6f 73 65 72 20 74 6f 20 74 68 65 20 73 74  closer to the st
22900 61 72 74 20 6f 66 20 74 68 65 20 66 69 6c 65 20  art of the file 
22910 28 61 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 74 68 65  (allowing.** the
22920 20 66 69 6c 65 20 74 6f 20 62 65 20 65 76 65 6e   file to be even
22930 74 75 61 6c 6c 79 20 74 72 75 6e 63 61 74 65 64  tually truncated
22940 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  )..*/.static int
22950 20 73 6f 72 74 65 64 4d 6f 76 65 42 6c 6f 63 6b   sortedMoveBlock
22960 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 69 6e  (lsm_db *pDb, in
22970 74 20 2a 70 6e 57 72 69 74 65 29 7b 0a 20 20 53  t *pnWrite){.  S
22980 6e 61 70 73 68 6f 74 20 2a 70 20 3d 20 70 44 62  napshot *p = pDb
22990 2d 3e 70 57 6f 72 6b 65 72 3b 0a 20 20 4c 65 76  ->pWorker;.  Lev
229a0 65 6c 20 2a 70 4c 76 6c 20 3d 20 6c 73 6d 44 62  el *pLvl = lsmDb
229b0 53 6e 61 70 73 68 6f 74 4c 65 76 65 6c 28 70 29  SnapshotLevel(p)
229c0 3b 0a 20 20 69 6e 74 20 69 46 72 6f 6d 3b 20 20  ;.  int iFrom;  
229d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
229e0 20 20 20 20 2f 2a 20 42 6c 6f 63 6b 20 74 6f 20      /* Block to 
229f0 6d 6f 76 65 20 2a 2f 0a 20 20 69 6e 74 20 69 54  move */.  int iT
22a00 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o;              
22a10 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73            /* Des
22a20 74 69 6e 61 74 69 6f 6e 20 74 6f 20 6d 6f 76 65  tination to move
22a30 20 62 6c 6f 63 6b 20 74 6f 20 2a 2f 0a 20 20 69   block to */.  i
22a40 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
22a50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
22a60 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
22a70 0a 0a 20 20 4d 6f 76 65 42 6c 6f 63 6b 43 74 78  ..  MoveBlockCtx
22a80 20 73 43 74 78 3b 0a 0a 20 20 61 73 73 65 72 74   sCtx;..  assert
22a90 28 20 70 4c 76 6c 2d 3e 70 4e 65 78 74 3d 3d 30  ( pLvl->pNext==0
22aa0 20 26 26 20 70 4c 76 6c 2d 3e 6e 52 69 67 68 74   && pLvl->nRight
22ab0 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
22ac0 20 70 2d 3e 72 65 64 69 72 65 63 74 2e 6e 3c 3d   p->redirect.n<=
22ad0 4c 53 4d 5f 4d 41 58 5f 42 4c 4f 43 4b 5f 52 45  LSM_MAX_BLOCK_RE
22ae0 44 49 52 45 43 54 53 20 29 3b 0a 0a 20 20 2a 70  DIRECTS );..  *p
22af0 6e 57 72 69 74 65 20 3d 20 30 3b 0a 0a 20 20 2f  nWrite = 0;..  /
22b00 2a 20 43 68 65 63 6b 20 74 68 61 74 20 74 68 65  * Check that the
22b10 20 72 65 64 69 72 65 63 74 20 61 72 72 61 79 20   redirect array 
22b20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 66  is not already f
22b30 75 6c 6c 2e 20 49 66 20 69 74 20 69 73 2c 20 72  ull. If it is, r
22b40 65 74 75 72 6e 0a 20 20 2a 2a 20 77 69 74 68 6f  eturn.  ** witho
22b50 75 74 20 6d 6f 76 69 6e 67 20 61 6e 79 20 64 61  ut moving any da
22b60 74 61 62 61 73 65 20 63 6f 6e 74 65 6e 74 2e 20  tabase content. 
22b70 20 2a 2f 0a 20 20 69 66 28 20 70 2d 3e 72 65 64   */.  if( p->red
22b80 69 72 65 63 74 2e 6e 3e 3d 4c 53 4d 5f 4d 41 58  irect.n>=LSM_MAX
22b90 5f 42 4c 4f 43 4b 5f 52 45 44 49 52 45 43 54 53  _BLOCK_REDIRECTS
22ba0 20 29 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b   ) return LSM_OK
22bb0 3b 0a 0a 20 20 2f 2a 20 46 69 6e 64 20 74 68 65  ;..  /* Find the
22bc0 20 6c 61 73 74 20 62 6c 6f 63 6b 20 6f 66 20 63   last block of c
22bd0 6f 6e 74 65 6e 74 20 69 6e 20 74 68 65 20 64 61  ontent in the da
22be0 74 61 62 61 73 65 20 66 69 6c 65 2e 20 44 6f 20  tabase file. Do 
22bf0 74 68 69 73 20 62 79 20 0a 20 20 2a 2a 20 74 72  this by .  ** tr
22c00 61 76 65 72 73 69 6e 67 20 74 68 65 20 66 72 65  aversing the fre
22c10 65 2d 6c 69 73 74 20 69 6e 20 72 65 76 65 72 73  e-list in revers
22c20 65 20 28 64 65 73 63 65 6e 64 69 6e 67 20 62 6c  e (descending bl
22c30 6f 63 6b 20 6e 75 6d 62 65 72 29 20 6f 72 64 65  ock number) orde
22c40 72 2e 0a 20 20 2a 2a 20 54 68 65 20 66 69 72 73  r..  ** The firs
22c50 74 20 62 6c 6f 63 6b 20 6e 6f 74 20 6f 6e 20 74  t block not on t
22c60 68 65 20 66 72 65 65 20 6c 69 73 74 20 69 73 20  he free list is 
22c70 74 68 65 20 6f 6e 65 20 74 68 61 74 20 77 69 6c  the one that wil
22c80 6c 20 62 65 20 6d 6f 76 65 64 2e 0a 20 20 2a 2a  l be moved..  **
22c90 20 53 69 6e 63 65 20 74 68 65 20 64 62 20 63 6f   Since the db co
22ca0 6e 73 69 73 74 73 20 6f 66 20 61 20 73 69 6e 67  nsists of a sing
22cb0 6c 65 20 73 65 67 6d 65 6e 74 2c 20 74 68 65 72  le segment, ther
22cc0 65 20 69 73 20 6e 6f 20 61 6d 62 69 67 75 69 74  e is no ambiguit
22cd0 79 20 61 73 0a 20 20 2a 2a 20 74 6f 20 77 68 69  y as.  ** to whi
22ce0 63 68 20 73 65 67 6d 65 6e 74 20 74 68 65 20 62  ch segment the b
22cf0 6c 6f 63 6b 20 62 65 6c 6f 6e 67 73 20 74 6f 2e  lock belongs to.
22d00 20 20 2a 2f 0a 20 20 73 43 74 78 2e 69 53 65 65    */.  sCtx.iSee
22d10 6e 20 3d 20 70 2d 3e 6e 42 6c 6f 63 6b 2b 31 3b  n = p->nBlock+1;
22d20 0a 20 20 73 43 74 78 2e 69 46 72 6f 6d 20 3d 20  .  sCtx.iFrom = 
22d30 30 3b 0a 20 20 72 63 20 3d 20 6c 73 6d 57 61 6c  0;.  rc = lsmWal
22d40 6b 46 72 65 65 6c 69 73 74 28 70 44 62 2c 20 31  kFreelist(pDb, 1
22d50 2c 20 6d 6f 76 65 42 6c 6f 63 6b 43 62 2c 20 26  , moveBlockCb, &
22d60 73 43 74 78 29 3b 0a 20 20 69 66 28 20 72 63 21  sCtx);.  if( rc!
22d70 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 73 43 74 78 2e  =LSM_OK || sCtx.
22d80 69 46 72 6f 6d 3d 3d 30 20 29 20 72 65 74 75 72  iFrom==0 ) retur
22d90 6e 20 72 63 3b 0a 20 20 69 46 72 6f 6d 20 3d 20  n rc;.  iFrom = 
22da0 73 43 74 78 2e 69 46 72 6f 6d 3b 0a 0a 20 20 2f  sCtx.iFrom;..  /
22db0 2a 20 46 69 6e 64 20 74 68 65 20 66 69 72 73 74  * Find the first
22dc0 20 66 72 65 65 20 62 6c 6f 63 6b 20 69 6e 20 74   free block in t
22dd0 68 65 20 64 61 74 61 62 61 73 65 2c 20 69 67 6e  he database, ign
22de0 6f 72 69 6e 67 20 62 6c 6f 63 6b 20 31 2e 20 42  oring block 1. B
22df0 6c 6f 63 6b 0a 20 20 2a 2a 20 31 20 69 73 20 74  lock.  ** 1 is t
22e00 72 69 63 6b 79 20 61 73 20 69 74 20 69 73 20 73  ricky as it is s
22e10 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74 68 65 20  maller than the 
22e20 6f 74 68 65 72 20 62 6c 6f 63 6b 73 2e 20 20 2a  other blocks.  *
22e30 2f 0a 20 20 72 63 20 3d 20 6c 73 6d 42 6c 6f 63  /.  rc = lsmBloc
22e40 6b 41 6c 6c 6f 63 61 74 65 28 70 44 62 2c 20 69  kAllocate(pDb, i
22e50 46 72 6f 6d 2c 20 26 69 54 6f 29 3b 0a 20 20 69  From, &iTo);.  i
22e60 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c 7c  f( rc!=LSM_OK ||
22e70 20 69 54 6f 3d 3d 30 20 29 20 72 65 74 75 72 6e   iTo==0 ) return
22e80 20 72 63 3b 0a 20 20 61 73 73 65 72 74 28 20 69   rc;.  assert( i
22e90 54 6f 21 3d 31 20 26 26 20 69 54 6f 3c 69 46 72  To!=1 && iTo<iFr
22ea0 6f 6d 20 29 3b 0a 0a 20 20 72 63 20 3d 20 6c 73  om );..  rc = ls
22eb0 6d 46 73 4d 6f 76 65 42 6c 6f 63 6b 28 70 44 62  mFsMoveBlock(pDb
22ec0 2d 3e 70 46 53 2c 20 26 70 4c 76 6c 2d 3e 6c 68  ->pFS, &pLvl->lh
22ed0 73 2c 20 69 54 6f 2c 20 69 46 72 6f 6d 29 3b 0a  s, iTo, iFrom);.
22ee0 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
22ef0 20 29 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e 72   ){.    if( p->r
22f00 65 64 69 72 65 63 74 2e 61 3d 3d 30 20 29 7b 0a  edirect.a==0 ){.
22f10 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20        int nByte 
22f20 3d 20 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20  = sizeof(struct 
22f30 52 65 64 69 72 65 63 74 45 6e 74 72 79 29 20 2a  RedirectEntry) *
22f40 20 4c 53 4d 5f 4d 41 58 5f 42 4c 4f 43 4b 5f 52   LSM_MAX_BLOCK_R
22f50 45 44 49 52 45 43 54 53 3b 0a 20 20 20 20 20 20  EDIRECTS;.      
22f60 70 2d 3e 72 65 64 69 72 65 63 74 2e 61 20 3d 20  p->redirect.a = 
22f70 6c 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28  lsmMallocZeroRc(
22f80 70 44 62 2d 3e 70 45 6e 76 2c 20 6e 42 79 74 65  pDb->pEnv, nByte
22f90 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d 0a 20 20  , &rc);.    }.  
22fa0 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
22fb0 20 29 7b 0a 0a 20 20 20 20 20 20 2f 2a 20 43 68   ){..      /* Ch
22fc0 65 63 6b 20 69 66 20 74 68 65 20 62 6c 6f 63 6b  eck if the block
22fd0 20 6a 75 73 74 20 6d 6f 76 65 64 20 77 61 73 20   just moved was 
22fe0 61 6c 72 65 61 64 79 20 72 65 64 69 72 65 63 74  already redirect
22ff0 65 64 2e 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  ed. */.      int
23000 20 69 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d   i;.      for(i=
23010 30 3b 20 69 3c 70 2d 3e 72 65 64 69 72 65 63 74  0; i<p->redirect
23020 2e 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  .n; i++){.      
23030 20 20 69 66 28 20 70 2d 3e 72 65 64 69 72 65 63    if( p->redirec
23040 74 2e 61 5b 69 5d 2e 69 54 6f 3d 3d 69 46 72 6f  t.a[i].iTo==iFro
23050 6d 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  m ) break;.     
23060 20 7d 0a 0a 20 20 20 20 20 20 69 66 28 20 69 3d   }..      if( i=
23070 3d 70 2d 3e 72 65 64 69 72 65 63 74 2e 6e 20 29  =p->redirect.n )
23080 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 42 6c 6f  {.        /* Blo
23090 63 6b 20 69 46 72 6f 6d 20 77 61 73 20 6e 6f 74  ck iFrom was not
230a0 20 61 6c 72 65 61 64 79 20 72 65 64 69 72 65 63   already redirec
230b0 74 65 64 2e 20 41 64 64 20 61 20 6e 65 77 20 61  ted. Add a new a
230c0 72 72 61 79 20 65 6e 74 72 79 2e 20 2a 2f 0a 20  rray entry. */. 
230d0 20 20 20 20 20 20 20 6d 65 6d 6d 6f 76 65 28 26         memmove(&
230e0 70 2d 3e 72 65 64 69 72 65 63 74 2e 61 5b 31 5d  p->redirect.a[1]
230f0 2c 20 26 70 2d 3e 72 65 64 69 72 65 63 74 2e 61  , &p->redirect.a
23100 5b 30 5d 2c 20 0a 20 20 20 20 20 20 20 20 20 20  [0], .          
23110 20 20 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20    sizeof(struct 
23120 52 65 64 69 72 65 63 74 45 6e 74 72 79 29 20 2a  RedirectEntry) *
23130 20 70 2d 3e 72 65 64 69 72 65 63 74 2e 6e 0a 20   p->redirect.n. 
23140 20 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20             );.  
23150 20 20 20 20 20 20 70 2d 3e 72 65 64 69 72 65 63        p->redirec
23160 74 2e 61 5b 30 5d 2e 69 46 72 6f 6d 20 3d 20 69  t.a[0].iFrom = i
23170 46 72 6f 6d 3b 0a 20 20 20 20 20 20 20 20 70 2d  From;.        p-
23180 3e 72 65 64 69 72 65 63 74 2e 61 5b 30 5d 2e 69  >redirect.a[0].i
23190 54 6f 20 3d 20 69 54 6f 3b 0a 20 20 20 20 20 20  To = iTo;.      
231a0 20 20 70 2d 3e 72 65 64 69 72 65 63 74 2e 6e 2b    p->redirect.n+
231b0 2b 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  +;.      }else{.
231c0 20 20 20 20 20 20 20 20 2f 2a 20 42 6c 6f 63 6b          /* Block
231d0 20 69 46 72 6f 6d 20 77 61 73 20 61 6c 72 65 61   iFrom was alrea
231e0 64 79 20 72 65 64 69 72 65 63 74 65 64 2e 20 4f  dy redirected. O
231f0 76 65 72 77 72 69 74 65 20 65 78 69 73 74 69 6e  verwrite existin
23200 67 20 65 6e 74 72 79 2e 20 2a 2f 0a 20 20 20 20  g entry. */.    
23210 20 20 20 20 70 2d 3e 72 65 64 69 72 65 63 74 2e      p->redirect.
23220 61 5b 69 5d 2e 69 54 6f 20 3d 20 69 54 6f 3b 0a  a[i].iTo = iTo;.
23230 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 72        }..      r
23240 63 20 3d 20 6c 73 6d 42 6c 6f 63 6b 46 72 65 65  c = lsmBlockFree
23250 28 70 44 62 2c 20 69 46 72 6f 6d 29 3b 0a 0a 20  (pDb, iFrom);.. 
23260 20 20 20 20 20 2a 70 6e 57 72 69 74 65 20 3d 20       *pnWrite = 
23270 6c 73 6d 46 73 42 6c 6f 63 6b 53 69 7a 65 28 70  lsmFsBlockSize(p
23280 44 62 2d 3e 70 46 53 29 20 2f 20 6c 73 6d 46 73  Db->pFS) / lsmFs
23290 50 61 67 65 53 69 7a 65 28 70 44 62 2d 3e 70 46  PageSize(pDb->pF
232a0 53 29 3b 0a 20 20 20 20 20 20 70 4c 76 6c 2d 3e  S);.      pLvl->
232b0 6c 68 73 2e 70 52 65 64 69 72 65 63 74 20 3d 20  lhs.pRedirect = 
232c0 26 70 2d 3e 72 65 64 69 72 65 63 74 3b 0a 20 20  &p->redirect;.  
232d0 20 20 7d 0a 20 20 7d 0a 0a 23 69 66 20 4c 53 4d    }.  }..#if LSM
232e0 5f 4c 4f 47 5f 53 54 52 55 43 54 55 52 45 0a 20  _LOG_STRUCTURE. 
232f0 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
23300 29 7b 0a 20 20 20 20 63 68 61 72 20 61 42 75 66  ){.    char aBuf
23310 5b 36 34 5d 3b 0a 20 20 20 20 73 70 72 69 6e 74  [64];.    sprint
23320 66 28 61 42 75 66 2c 20 22 6d 6f 76 65 2d 62 6c  f(aBuf, "move-bl
23330 6f 63 6b 20 25 64 2f 25 64 22 2c 20 70 2d 3e 72  ock %d/%d", p->r
23340 65 64 69 72 65 63 74 2e 6e 2d 31 2c 20 4c 53 4d  edirect.n-1, LSM
23350 5f 4d 41 58 5f 42 4c 4f 43 4b 5f 52 45 44 49 52  _MAX_BLOCK_REDIR
23360 45 43 54 53 29 3b 0a 20 20 20 20 6c 73 6d 53 6f  ECTS);.    lsmSo
23370 72 74 65 64 44 75 6d 70 53 74 72 75 63 74 75 72  rtedDumpStructur
23380 65 28 70 44 62 2c 20 70 44 62 2d 3e 70 57 6f 72  e(pDb, pDb->pWor
23390 6b 65 72 2c 20 4c 53 4d 5f 4c 4f 47 5f 44 41 54  ker, LSM_LOG_DAT
233a0 41 2c 20 30 2c 20 61 42 75 66 29 3b 0a 20 20 7d  A, 0, aBuf);.  }
233b0 0a 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72 6e  .#endif.  return
233c0 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2f 0a 73 74   rc;.}../*.*/.st
233d0 61 74 69 63 20 69 6e 74 20 6d 65 72 67 65 49 6e  atic int mergeIn
233e0 73 65 72 74 46 72 65 65 6c 69 73 74 53 65 67 6d  sertFreelistSegm
233f0 65 6e 74 73 28 0a 20 20 6c 73 6d 5f 64 62 20 2a  ents(.  lsm_db *
23400 70 44 62 2c 20 0a 20 20 69 6e 74 20 6e 46 72 65  pDb, .  int nFre
23410 65 2c 0a 20 20 4d 65 72 67 65 57 6f 72 6b 65 72  e,.  MergeWorker
23420 20 2a 70 4d 57 0a 29 7b 0a 20 20 69 6e 74 20 72   *pMW.){.  int r
23430 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 69 66  c = LSM_OK;.  if
23440 28 20 6e 46 72 65 65 3e 30 20 29 7b 0a 20 20 20  ( nFree>0 ){.   
23450 20 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43   MultiCursor *pC
23460 73 72 20 3d 20 70 4d 57 2d 3e 70 43 73 72 3b 0a  sr = pMW->pCsr;.
23470 20 20 20 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 20      Level *pLvl 
23480 3d 20 70 4d 57 2d 3e 70 4c 65 76 65 6c 3b 0a 20  = pMW->pLevel;. 
23490 20 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 61     SegmentPtr *a
234a0 4e 65 77 31 3b 0a 20 20 20 20 53 65 67 6d 65 6e  New1;.    Segmen
234b0 74 20 2a 61 4e 65 77 32 3b 0a 0a 20 20 20 20 4c  t *aNew2;..    L
234c0 65 76 65 6c 20 2a 70 49 74 65 72 3b 0a 20 20 20  evel *pIter;.   
234d0 20 4c 65 76 65 6c 20 2a 70 4e 65 78 74 3b 0a 20   Level *pNext;. 
234e0 20 20 20 69 6e 74 20 69 20 3d 20 30 3b 0a 0a 20     int i = 0;.. 
234f0 20 20 20 61 4e 65 77 31 20 3d 20 28 53 65 67 6d     aNew1 = (Segm
23500 65 6e 74 50 74 72 20 2a 29 6c 73 6d 4d 61 6c 6c  entPtr *)lsmMall
23510 6f 63 5a 65 72 6f 52 63 28 0a 20 20 20 20 20 20  ocZeroRc(.      
23520 20 20 70 44 62 2d 3e 70 45 6e 76 2c 20 73 69 7a    pDb->pEnv, siz
23530 65 6f 66 28 53 65 67 6d 65 6e 74 50 74 72 29 20  eof(SegmentPtr) 
23540 2a 20 28 70 43 73 72 2d 3e 6e 50 74 72 2b 6e 46  * (pCsr->nPtr+nF
23550 72 65 65 29 2c 20 26 72 63 0a 20 20 20 20 29 3b  ree), &rc.    );
23560 0a 20 20 20 20 69 66 28 20 72 63 20 29 20 72 65  .    if( rc ) re
23570 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 6d 65 6d  turn rc;.    mem
23580 63 70 79 28 26 61 4e 65 77 31 5b 6e 46 72 65 65  cpy(&aNew1[nFree
23590 5d 2c 20 70 43 73 72 2d 3e 61 50 74 72 2c 20 73  ], pCsr->aPtr, s
235a0 69 7a 65 6f 66 28 53 65 67 6d 65 6e 74 50 74 72  izeof(SegmentPtr
235b0 29 2a 70 43 73 72 2d 3e 6e 50 74 72 29 3b 0a 20  )*pCsr->nPtr);. 
235c0 20 20 20 70 43 73 72 2d 3e 6e 50 74 72 20 2b 3d     pCsr->nPtr +=
235d0 20 6e 46 72 65 65 3b 0a 20 20 20 20 6c 73 6d 46   nFree;.    lsmF
235e0 72 65 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70  ree(pDb->pEnv, p
235f0 43 73 72 2d 3e 61 54 72 65 65 29 3b 0a 20 20 20  Csr->aTree);.   
23600 20 6c 73 6d 46 72 65 65 28 70 44 62 2d 3e 70 45   lsmFree(pDb->pE
23610 6e 76 2c 20 70 43 73 72 2d 3e 61 50 74 72 29 3b  nv, pCsr->aPtr);
23620 0a 20 20 20 20 70 43 73 72 2d 3e 61 54 72 65 65  .    pCsr->aTree
23630 20 3d 20 30 3b 0a 20 20 20 20 70 43 73 72 2d 3e   = 0;.    pCsr->
23640 61 50 74 72 20 3d 20 61 4e 65 77 31 3b 0a 0a 20  aPtr = aNew1;.. 
23650 20 20 20 61 4e 65 77 32 20 3d 20 28 53 65 67 6d     aNew2 = (Segm
23660 65 6e 74 20 2a 29 6c 73 6d 4d 61 6c 6c 6f 63 5a  ent *)lsmMallocZ
23670 65 72 6f 52 63 28 0a 20 20 20 20 20 20 20 20 70  eroRc(.        p
23680 44 62 2d 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66  Db->pEnv, sizeof
23690 28 53 65 67 6d 65 6e 74 29 20 2a 20 28 70 4c 76  (Segment) * (pLv
236a0 6c 2d 3e 6e 52 69 67 68 74 2b 6e 46 72 65 65 29  l->nRight+nFree)
236b0 2c 20 26 72 63 0a 20 20 20 20 29 3b 0a 20 20 20  , &rc.    );.   
236c0 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e   if( rc ) return
236d0 20 72 63 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28   rc;.    memcpy(
236e0 26 61 4e 65 77 32 5b 6e 46 72 65 65 5d 2c 20 70  &aNew2[nFree], p
236f0 4c 76 6c 2d 3e 61 52 68 73 2c 20 73 69 7a 65 6f  Lvl->aRhs, sizeo
23700 66 28 53 65 67 6d 65 6e 74 29 2a 70 4c 76 6c 2d  f(Segment)*pLvl-
23710 3e 6e 52 69 67 68 74 29 3b 0a 20 20 20 20 70 4c  >nRight);.    pL
23720 76 6c 2d 3e 6e 52 69 67 68 74 20 2b 3d 20 6e 46  vl->nRight += nF
23730 72 65 65 3b 0a 20 20 20 20 6c 73 6d 46 72 65 65  ree;.    lsmFree
23740 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70 4c 76 6c  (pDb->pEnv, pLvl
23750 2d 3e 61 52 68 73 29 3b 0a 20 20 20 20 70 4c 76  ->aRhs);.    pLv
23760 6c 2d 3e 61 52 68 73 20 3d 20 61 4e 65 77 32 3b  l->aRhs = aNew2;
23770 0a 0a 20 20 20 20 66 6f 72 28 70 49 74 65 72 3d  ..    for(pIter=
23780 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2d 3e 70 4c  pDb->pWorker->pL
23790 65 76 65 6c 3b 20 72 63 3d 3d 4c 53 4d 5f 4f 4b  evel; rc==LSM_OK
237a0 20 26 26 20 70 49 74 65 72 21 3d 70 4c 76 6c 3b   && pIter!=pLvl;
237b0 20 70 49 74 65 72 3d 70 4e 65 78 74 29 7b 0a 20   pIter=pNext){. 
237c0 20 20 20 20 20 53 65 67 6d 65 6e 74 20 2a 70 53       Segment *pS
237d0 65 67 20 3d 20 26 70 4c 76 6c 2d 3e 61 52 68 73  eg = &pLvl->aRhs
237e0 5b 69 5d 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70  [i];.      memcp
237f0 79 28 70 53 65 67 2c 20 26 70 49 74 65 72 2d 3e  y(pSeg, &pIter->
23800 6c 68 73 2c 20 73 69 7a 65 6f 66 28 53 65 67 6d  lhs, sizeof(Segm
23810 65 6e 74 29 29 3b 0a 0a 20 20 20 20 20 20 70 43  ent));..      pC
23820 73 72 2d 3e 61 50 74 72 5b 69 5d 2e 70 53 65 67  sr->aPtr[i].pSeg
23830 20 3d 20 70 53 65 67 3b 0a 20 20 20 20 20 20 70   = pSeg;.      p
23840 43 73 72 2d 3e 61 50 74 72 5b 69 5d 2e 70 4c 65  Csr->aPtr[i].pLe
23850 76 65 6c 20 3d 20 70 4c 76 6c 3b 0a 20 20 20 20  vel = pLvl;.    
23860 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74    rc = segmentPt
23870 72 45 6e 64 28 70 43 73 72 2c 20 26 70 43 73 72  rEnd(pCsr, &pCsr
23880 2d 3e 61 50 74 72 5b 69 5d 2c 20 30 29 3b 0a 0a  ->aPtr[i], 0);..
23890 20 20 20 20 20 20 70 44 62 2d 3e 70 57 6f 72 6b        pDb->pWork
238a0 65 72 2d 3e 70 4c 65 76 65 6c 20 3d 20 70 4e 65  er->pLevel = pNe
238b0 78 74 20 3d 20 70 49 74 65 72 2d 3e 70 4e 65 78  xt = pIter->pNex
238c0 74 3b 0a 20 20 20 20 20 20 73 6f 72 74 65 64 46  t;.      sortedF
238d0 72 65 65 4c 65 76 65 6c 28 70 44 62 2d 3e 70 45  reeLevel(pDb->pE
238e0 6e 76 2c 20 70 49 74 65 72 29 3b 0a 20 20 20 20  nv, pIter);.    
238f0 20 20 69 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20    i++;.    }.   
23900 20 61 73 73 65 72 74 28 20 69 3d 3d 6e 46 72 65   assert( i==nFre
23910 65 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  e );.    assert(
23920 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 70   rc!=LSM_OK || p
23930 44 62 2d 3e 70 57 6f 72 6b 65 72 2d 3e 70 4c 65  Db->pWorker->pLe
23940 76 65 6c 3d 3d 70 4c 76 6c 20 29 3b 0a 0a 20 20  vel==pLvl );..  
23950 20 20 66 6f 72 28 69 3d 6e 46 72 65 65 3b 20 69    for(i=nFree; i
23960 3c 70 43 73 72 2d 3e 6e 50 74 72 3b 20 69 2b 2b  <pCsr->nPtr; i++
23970 29 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 61  ){.      pCsr->a
23980 50 74 72 5b 69 5d 2e 70 53 65 67 20 3d 20 26 70  Ptr[i].pSeg = &p
23990 4c 76 6c 2d 3e 61 52 68 73 5b 69 5d 3b 0a 20 20  Lvl->aRhs[i];.  
239a0 20 20 7d 0a 0a 20 20 20 20 6c 73 6d 46 72 65 65    }..    lsmFree
239b0 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70 4d 57 2d  (pDb->pEnv, pMW-
239c0 3e 61 47 6f 62 62 6c 65 29 3b 0a 20 20 20 20 70  >aGobble);.    p
239d0 4d 57 2d 3e 61 47 6f 62 62 6c 65 20 3d 20 30 3b  MW->aGobble = 0;
239e0 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
239f0 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
23a00 73 6f 72 74 65 64 57 6f 72 6b 28 0a 20 20 6c 73  sortedWork(.  ls
23a10 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20 20 20 20  m_db *pDb,      
23a20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
23a30 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65   Database handle
23a40 2e 20 4d 75 73 74 20 62 65 20 77 6f 72 6b 65 72  . Must be worker
23a50 2e 20 2a 2f 0a 20 20 69 6e 74 20 6e 57 6f 72 6b  . */.  int nWork
23a60 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
23a70 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
23a80 20 6f 66 20 70 61 67 65 73 20 6f 66 20 77 6f 72   of pages of wor
23a90 6b 20 74 6f 20 64 6f 20 2a 2f 0a 20 20 69 6e 74  k to do */.  int
23aa0 20 6e 4d 65 72 67 65 2c 20 20 20 20 20 20 20 20   nMerge,        
23ab0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
23ac0 54 72 79 20 74 6f 20 6d 65 72 67 65 20 74 68 69  Try to merge thi
23ad0 73 20 6d 61 6e 79 20 6c 65 76 65 6c 73 20 61 74  s many levels at
23ae0 20 6f 6e 63 65 20 2a 2f 0a 20 20 69 6e 74 20 62   once */.  int b
23af0 46 6c 75 73 68 2c 20 20 20 20 20 20 20 20 20 20  Flush,          
23b00 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65             /* Se
23b10 74 20 69 66 20 63 61 6c 6c 20 69 73 20 74 6f 20  t if call is to 
23b20 6d 61 6b 65 20 72 6f 6f 6d 20 66 6f 72 20 61 20  make room for a 
23b30 66 6c 75 73 68 20 2a 2f 0a 20 20 69 6e 74 20 2a  flush */.  int *
23b40 70 6e 57 72 69 74 65 20 20 20 20 20 20 20 20 20  pnWrite         
23b50 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
23b60 54 3a 20 41 63 74 75 61 6c 20 6e 75 6d 62 65 72  T: Actual number
23b70 20 6f 66 20 70 61 67 65 73 20 77 72 69 74 74 65   of pages writte
23b80 6e 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  n */.){.  int rc
23b90 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20   = LSM_OK;      
23ba0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
23bb0 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 69 6e  urn Code */.  in
23bc0 74 20 6e 52 65 6d 61 69 6e 69 6e 67 20 3d 20 6e  t nRemaining = n
23bd0 57 6f 72 6b 3b 20 20 20 20 20 20 20 20 20 2f 2a  Work;         /*
23be0 20 55 6e 69 74 73 20 6f 66 20 77 6f 72 6b 20 74   Units of work t
23bf0 6f 20 64 6f 20 62 65 66 6f 72 65 20 72 65 74 75  o do before retu
23c00 72 6e 69 6e 67 20 2a 2f 0a 20 20 53 6e 61 70 73  rning */.  Snaps
23c10 68 6f 74 20 2a 70 57 6f 72 6b 65 72 20 3d 20 70  hot *pWorker = p
23c20 44 62 2d 3e 70 57 6f 72 6b 65 72 3b 0a 0a 20 20  Db->pWorker;..  
23c30 61 73 73 65 72 74 28 20 70 57 6f 72 6b 65 72 20  assert( pWorker 
23c40 29 3b 0a 20 20 69 66 28 20 6c 73 6d 44 62 53 6e  );.  if( lsmDbSn
23c50 61 70 73 68 6f 74 4c 65 76 65 6c 28 70 57 6f 72  apshotLevel(pWor
23c60 6b 65 72 29 3d 3d 30 20 29 20 72 65 74 75 72 6e  ker)==0 ) return
23c70 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20 20 77 68 69 6c   LSM_OK;..  whil
23c80 65 28 20 6e 52 65 6d 61 69 6e 69 6e 67 3e 30 20  e( nRemaining>0 
23c90 29 7b 0a 20 20 20 20 4c 65 76 65 6c 20 2a 70 4c  ){.    Level *pL
23ca0 65 76 65 6c 20 3d 20 30 3b 0a 0a 20 20 20 20 2f  evel = 0;..    /
23cb0 2a 20 46 69 6e 64 20 61 20 6c 65 76 65 6c 20 74  * Find a level t
23cc0 6f 20 77 6f 72 6b 20 6f 6e 2e 20 2a 2f 0a 20 20  o work on. */.  
23cd0 20 20 72 63 20 3d 20 73 6f 72 74 65 64 53 65 6c    rc = sortedSel
23ce0 65 63 74 4c 65 76 65 6c 28 70 44 62 2c 20 6e 4d  ectLevel(pDb, nM
23cf0 65 72 67 65 2c 20 26 70 4c 65 76 65 6c 29 3b 0a  erge, &pLevel);.
23d00 20 20 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d      assert( rc==
23d10 4c 53 4d 5f 4f 4b 20 7c 7c 20 70 4c 65 76 65 6c  LSM_OK || pLevel
23d20 3d 3d 30 20 29 3b 0a 0a 20 20 20 20 69 66 28 20  ==0 );..    if( 
23d30 70 4c 65 76 65 6c 3d 3d 30 20 29 7b 0a 20 20 20  pLevel==0 ){.   
23d40 20 20 20 69 6e 74 20 6e 44 6f 6e 65 20 3d 20 30     int nDone = 0
23d50 3b 0a 20 20 20 20 20 20 4c 65 76 65 6c 20 2a 70  ;.      Level *p
23d60 54 6f 70 4c 65 76 65 6c 20 3d 20 6c 73 6d 44 62  TopLevel = lsmDb
23d70 53 6e 61 70 73 68 6f 74 4c 65 76 65 6c 28 70 44  SnapshotLevel(pD
23d80 62 2d 3e 70 57 6f 72 6b 65 72 29 3b 0a 20 20 20  b->pWorker);.   
23d90 20 20 20 69 66 28 20 62 46 6c 75 73 68 3d 3d 30     if( bFlush==0
23da0 20 26 26 20 6e 4d 65 72 67 65 3d 3d 31 20 26 26   && nMerge==1 &&
23db0 20 70 54 6f 70 4c 65 76 65 6c 20 26 26 20 70 54   pTopLevel && pT
23dc0 6f 70 4c 65 76 65 6c 2d 3e 70 4e 65 78 74 3d 3d  opLevel->pNext==
23dd0 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  0 ){.        rc 
23de0 3d 20 73 6f 72 74 65 64 4d 6f 76 65 42 6c 6f 63  = sortedMoveBloc
23df0 6b 28 70 44 62 2c 20 26 6e 44 6f 6e 65 29 3b 0a  k(pDb, &nDone);.
23e00 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 6e 52        }.      nR
23e10 65 6d 61 69 6e 69 6e 67 20 2d 3d 20 6e 44 6f 6e  emaining -= nDon
23e20 65 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 43 6f 75  e;..      /* Cou
23e30 6c 64 20 6e 6f 74 20 66 69 6e 64 20 61 6e 79 20  ld not find any 
23e40 77 6f 72 6b 20 74 6f 20 64 6f 2e 20 46 69 6e 69  work to do. Fini
23e50 73 68 65 64 2e 20 2a 2f 0a 20 20 20 20 20 20 69  shed. */.      i
23e60 66 28 20 6e 44 6f 6e 65 3d 3d 30 20 29 20 62 72  f( nDone==0 ) br
23e70 65 61 6b 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  eak;.    }else{.
23e80 20 20 20 20 20 20 69 6e 74 20 62 53 61 76 65 20        int bSave 
23e90 3d 20 30 3b 0a 20 20 20 20 20 20 46 72 65 65 6c  = 0;.      Freel
23ea0 69 73 74 20 66 72 65 65 6c 69 73 74 20 3d 20 7b  ist freelist = {
23eb0 30 2c 20 30 2c 20 30 7d 3b 0a 20 20 20 20 20 20  0, 0, 0};.      
23ec0 4d 65 72 67 65 57 6f 72 6b 65 72 20 6d 65 72 67  MergeWorker merg
23ed0 65 77 6f 72 6b 65 72 3b 20 20 20 20 2f 2a 20 53  eworker;    /* S
23ee0 74 61 74 65 20 75 73 65 64 20 74 6f 20 77 6f 72  tate used to wor
23ef0 6b 20 6f 6e 20 74 68 65 20 6c 65 76 65 6c 20 6d  k on the level m
23f00 65 72 67 65 20 2a 2f 0a 0a 20 20 20 20 20 20 61  erge */..      a
23f10 73 73 65 72 74 28 20 70 44 62 2d 3e 62 49 6e 63  ssert( pDb->bInc
23f20 72 4d 65 72 67 65 3d 3d 30 20 29 3b 0a 20 20 20  rMerge==0 );.   
23f30 20 20 20 61 73 73 65 72 74 28 20 70 44 62 2d 3e     assert( pDb->
23f40 70 46 72 65 65 6c 69 73 74 3d 3d 30 20 26 26 20  pFreelist==0 && 
23f50 70 44 62 2d 3e 62 55 73 65 46 72 65 65 6c 69 73  pDb->bUseFreelis
23f60 74 3d 3d 30 20 29 3b 0a 0a 20 20 20 20 20 20 70  t==0 );..      p
23f70 44 62 2d 3e 62 49 6e 63 72 4d 65 72 67 65 20 3d  Db->bIncrMerge =
23f80 20 31 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 6d   1;.      rc = m
23f90 65 72 67 65 57 6f 72 6b 65 72 49 6e 69 74 28 70  ergeWorkerInit(p
23fa0 44 62 2c 20 70 4c 65 76 65 6c 2c 20 26 6d 65 72  Db, pLevel, &mer
23fb0 67 65 77 6f 72 6b 65 72 29 3b 0a 20 20 20 20 20  geworker);.     
23fc0 20 61 73 73 65 72 74 28 20 6d 65 72 67 65 77 6f   assert( mergewo
23fd0 72 6b 65 72 2e 6e 57 6f 72 6b 3d 3d 30 20 29 3b  rker.nWork==0 );
23fe0 0a 20 20 20 20 20 20 0a 20 20 20 20 20 20 77 68  .      .      wh
23ff0 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20  ile( rc==LSM_OK 
24000 0a 20 20 20 20 20 20 20 20 20 20 26 26 20 30 3d  .          && 0=
24010 3d 6d 65 72 67 65 57 6f 72 6b 65 72 44 6f 6e 65  =mergeWorkerDone
24020 28 26 6d 65 72 67 65 77 6f 72 6b 65 72 29 20 0a  (&mergeworker) .
24030 20 20 20 20 20 20 20 20 20 20 26 26 20 28 6d 65            && (me
24040 72 67 65 77 6f 72 6b 65 72 2e 6e 57 6f 72 6b 3c  rgeworker.nWork<
24050 6e 52 65 6d 61 69 6e 69 6e 67 20 7c 7c 20 70 44  nRemaining || pD
24060 62 2d 3e 62 55 73 65 46 72 65 65 6c 69 73 74 29  b->bUseFreelist)
24070 0a 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20  .      ){.      
24080 20 20 69 6e 74 20 65 54 79 70 65 20 3d 20 72 74    int eType = rt
24090 54 6f 70 69 63 28 6d 65 72 67 65 77 6f 72 6b 65  Topic(mergeworke
240a0 72 2e 70 43 73 72 2d 3e 65 54 79 70 65 29 3b 0a  r.pCsr->eType);.
240b0 20 20 20 20 20 20 20 20 72 63 20 3d 20 6d 65 72          rc = mer
240c0 67 65 57 6f 72 6b 65 72 53 74 65 70 28 26 6d 65  geWorkerStep(&me
240d0 72 67 65 77 6f 72 6b 65 72 29 3b 0a 0a 20 20 20  rgeworker);..   
240e0 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 63       /* If the c
240f0 75 72 73 6f 72 20 6e 6f 77 20 70 6f 69 6e 74 73  ursor now points
24100 20 61 74 20 74 68 65 20 66 69 72 73 74 20 65 6e   at the first en
24110 74 72 79 20 70 61 73 74 20 74 68 65 20 65 6e 64  try past the end
24120 20 6f 66 20 74 68 65 0a 20 20 20 20 20 20 20 20   of the.        
24130 2a 2a 20 75 73 65 72 20 64 61 74 61 20 28 69 2e  ** user data (i.
24140 65 2e 20 65 69 74 68 65 72 20 74 6f 20 45 4f 46  e. either to EOF
24150 20 6f 72 20 74 6f 20 74 68 65 20 66 69 72 73 74   or to the first
24160 20 66 72 65 65 2d 6c 69 73 74 20 65 6e 74 72 79   free-list entry
24170 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 68 61 74  .        ** that
24180 20 77 69 6c 6c 20 62 65 20 61 64 64 65 64 20 74   will be added t
24190 6f 20 74 68 65 20 72 75 6e 29 2c 20 74 68 65 6e  o the run), then
241a0 20 63 68 65 63 6b 20 69 66 20 69 74 20 69 73 20   check if it is 
241b0 70 6f 73 73 69 62 6c 65 20 74 6f 0a 20 20 20 20  possible to.    
241c0 20 20 20 20 2a 2a 20 6d 65 72 67 65 20 69 6e 20      ** merge in 
241d0 61 6e 79 20 66 72 65 65 2d 6c 69 73 74 20 65 6e  any free-list en
241e0 74 72 69 65 73 20 74 68 61 74 20 61 72 65 20 65  tries that are e
241f0 69 74 68 65 72 20 69 6e 2d 6d 65 6d 6f 72 79 20  ither in-memory 
24200 6f 72 20 69 6e 0a 20 20 20 20 20 20 20 20 2a 2a  or in.        **
24210 20 66 72 65 65 2d 6c 69 73 74 2d 6f 6e 6c 79 20   free-list-only 
24220 62 6c 6f 63 6b 73 2e 20 20 2a 2f 0a 20 20 20 20  blocks.  */.    
24230 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f      if( rc==LSM_
24240 4f 4b 20 26 26 20 6e 4d 65 72 67 65 3d 3d 31 20  OK && nMerge==1 
24250 26 26 20 65 54 79 70 65 3d 3d 30 0a 20 20 20 20  && eType==0.    
24260 20 20 20 20 20 26 26 20 28 72 74 54 6f 70 69 63       && (rtTopic
24270 28 6d 65 72 67 65 77 6f 72 6b 65 72 2e 70 43 73  (mergeworker.pCs
24280 72 2d 3e 65 54 79 70 65 29 20 7c 7c 20 6d 65 72  r->eType) || mer
24290 67 65 57 6f 72 6b 65 72 44 6f 6e 65 28 26 6d 65  geWorkerDone(&me
242a0 72 67 65 77 6f 72 6b 65 72 29 29 0a 20 20 20 20  rgeworker)).    
242b0 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20      ){.         
242c0 20 69 6e 74 20 6e 46 72 65 65 20 3d 20 30 3b 20   int nFree = 0; 
242d0 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
242e0 65 72 20 6f 66 20 66 72 65 65 2d 6c 69 73 74 2d  er of free-list-
242f0 6f 6e 6c 79 20 6c 65 76 65 6c 73 20 74 6f 20 6d  only levels to m
24300 65 72 67 65 20 2a 2f 0a 20 20 20 20 20 20 20 20  erge */.        
24310 20 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 3b 0a 20    Level *pLvl;. 
24320 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
24330 20 70 44 62 2d 3e 70 46 72 65 65 6c 69 73 74 3d   pDb->pFreelist=
24340 3d 30 20 26 26 20 70 44 62 2d 3e 62 55 73 65 46  =0 && pDb->bUseF
24350 72 65 65 6c 69 73 74 3d 3d 30 20 29 3b 0a 0a 20  reelist==0 );.. 
24360 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 77 20           /* Now 
24370 63 68 65 63 6b 20 69 66 20 61 6c 6c 20 6c 65 76  check if all lev
24380 65 6c 73 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64  els containing d
24390 61 74 61 20 6e 65 77 65 72 20 74 68 61 6e 20 74  ata newer than t
243a0 68 69 73 20 6f 6e 65 0a 20 20 20 20 20 20 20 20  his one.        
243b0 20 20 2a 2a 20 61 72 65 20 73 69 6e 67 6c 65 2d    ** are single-
243c0 73 65 67 6d 65 6e 74 20 66 72 65 65 2d 6c 69 73  segment free-lis
243d0 74 20 6f 6e 6c 79 20 6c 65 76 65 6c 73 2e 20 49  t only levels. I
243e0 66 20 73 6f 2c 20 74 68 65 79 20 77 69 6c 6c 20  f so, they will 
243f0 62 65 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20  be.          ** 
24400 6d 65 72 67 65 64 20 69 6e 20 6e 6f 77 2e 20 20  merged in now.  
24410 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 66 6f 72  */.          for
24420 28 70 4c 76 6c 3d 70 44 62 2d 3e 70 57 6f 72 6b  (pLvl=pDb->pWork
24430 65 72 2d 3e 70 4c 65 76 65 6c 3b 20 0a 20 20 20  er->pLevel; .   
24440 20 20 20 20 20 20 20 20 20 20 20 70 4c 76 6c 21             pLvl!
24450 3d 6d 65 72 67 65 77 6f 72 6b 65 72 2e 70 4c 65  =mergeworker.pLe
24460 76 65 6c 20 26 26 20 28 70 4c 76 6c 2d 3e 66 6c  vel && (pLvl->fl
24470 61 67 73 20 26 20 4c 45 56 45 4c 5f 46 52 45 45  ags & LEVEL_FREE
24480 4c 49 53 54 5f 4f 4e 4c 59 29 3b 20 0a 20 20 20  LIST_ONLY); .   
24490 20 20 20 20 20 20 20 20 20 20 20 70 4c 76 6c 3d             pLvl=
244a0 70 4c 76 6c 2d 3e 70 4e 65 78 74 0a 20 20 20 20  pLvl->pNext.    
244b0 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20        ){.       
244c0 20 20 20 20 20 61 73 73 65 72 74 28 20 70 4c 76       assert( pLv
244d0 6c 2d 3e 6e 52 69 67 68 74 3d 3d 30 20 29 3b 0a  l->nRight==0 );.
244e0 20 20 20 20 20 20 20 20 20 20 20 20 6e 46 72 65              nFre
244f0 65 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  e++;.          }
24500 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 70  .          if( p
24510 4c 76 6c 3d 3d 6d 65 72 67 65 77 6f 72 6b 65 72  Lvl==mergeworker
24520 2e 70 4c 65 76 65 6c 20 29 7b 0a 0a 20 20 20 20  .pLevel ){..    
24530 20 20 20 20 20 20 20 20 72 63 20 3d 20 6d 65 72          rc = mer
24540 67 65 49 6e 73 65 72 74 46 72 65 65 6c 69 73 74  geInsertFreelist
24550 53 65 67 6d 65 6e 74 73 28 70 44 62 2c 20 6e 46  Segments(pDb, nF
24560 72 65 65 2c 20 26 6d 65 72 67 65 77 6f 72 6b 65  ree, &mergeworke
24570 72 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  r);.            
24580 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
24590 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  {.              
245a0 72 63 20 3d 20 6d 75 6c 74 69 43 75 72 73 6f 72  rc = multiCursor
245b0 56 69 73 69 74 46 72 65 65 6c 69 73 74 28 6d 65  VisitFreelist(me
245c0 72 67 65 77 6f 72 6b 65 72 2e 70 43 73 72 29 3b  rgeworker.pCsr);
245d0 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20  .            }. 
245e0 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20 72             if( r
245f0 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
24600 20 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20             rc = 
24610 6d 75 6c 74 69 43 75 72 73 6f 72 53 65 74 75 70  multiCursorSetup
24620 54 72 65 65 28 6d 65 72 67 65 77 6f 72 6b 65 72  Tree(mergeworker
24630 2e 70 43 73 72 2c 20 30 29 3b 0a 20 20 20 20 20  .pCsr, 0);.     
24640 20 20 20 20 20 20 20 20 20 70 44 62 2d 3e 70 46           pDb->pF
24650 72 65 65 6c 69 73 74 20 3d 20 26 66 72 65 65 6c  reelist = &freel
24660 69 73 74 3b 0a 20 20 20 20 20 20 20 20 20 20 20  ist;.           
24670 20 20 20 70 44 62 2d 3e 62 55 73 65 46 72 65 65     pDb->bUseFree
24680 6c 69 73 74 20 3d 20 31 3b 0a 20 20 20 20 20 20  list = 1;.      
24690 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
246a0 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20    }.        }.  
246b0 20 20 20 20 7d 0a 20 20 20 20 20 20 6e 52 65 6d      }.      nRem
246c0 61 69 6e 69 6e 67 20 2d 3d 20 4c 53 4d 5f 4d 41  aining -= LSM_MA
246d0 58 28 6d 65 72 67 65 77 6f 72 6b 65 72 2e 6e 57  X(mergeworker.nW
246e0 6f 72 6b 2c 20 31 29 3b 0a 0a 20 20 20 20 20 20  ork, 1);..      
246f0 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
24700 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65  {.        /* Che
24710 63 6b 20 69 66 20 74 68 65 20 6d 65 72 67 65 20  ck if the merge 
24720 6f 70 65 72 61 74 69 6f 6e 20 69 73 20 63 6f 6d  operation is com
24730 70 6c 65 74 65 6c 79 20 66 69 6e 69 73 68 65 64  pletely finished
24740 2e 20 49 66 20 6e 6f 74 2c 0a 20 20 20 20 20 20  . If not,.      
24750 20 20 2a 2a 20 67 6f 62 62 6c 65 20 75 70 20 28    ** gobble up (
24760 64 65 63 6c 61 72 65 20 65 6c 69 67 69 62 6c 65  declare eligible
24770 20 66 6f 72 20 72 65 63 79 63 6c 69 6e 67 29 20   for recycling) 
24780 61 6e 79 20 70 61 67 65 73 20 66 72 6f 6d 20 72  any pages from r
24790 68 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 65  hs.        ** se
247a0 67 6d 65 6e 74 73 20 66 6f 72 20 77 68 69 63 68  gments for which
247b0 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 68 61 73   the content has
247c0 20 62 65 65 6e 20 63 6f 6d 70 6c 65 74 65 6c 79   been completely
247d0 20 6d 65 72 67 65 64 20 69 6e 74 6f 20 0a 20 20   merged into .  
247e0 20 20 20 20 20 20 2a 2a 20 74 68 65 20 6c 68 73        ** the lhs
247f0 20 6f 66 20 74 68 65 20 6c 65 76 65 6c 2e 20 20   of the level.  
24800 2a 2f 0a 20 20 20 20 20 20 20 20 69 66 28 20 6d  */.        if( m
24810 65 72 67 65 57 6f 72 6b 65 72 44 6f 6e 65 28 26  ergeWorkerDone(&
24820 6d 65 72 67 65 77 6f 72 6b 65 72 29 3d 3d 30 20  mergeworker)==0 
24830 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74  ){.          int
24840 20 69 3b 0a 20 20 20 20 20 20 20 20 20 20 66 6f   i;.          fo
24850 72 28 69 3d 30 3b 20 69 3c 70 4c 65 76 65 6c 2d  r(i=0; i<pLevel-
24860 3e 6e 52 69 67 68 74 3b 20 69 2b 2b 29 7b 0a 20  >nRight; i++){. 
24870 20 20 20 20 20 20 20 20 20 20 20 53 65 67 6d 65             Segme
24880 6e 74 50 74 72 20 2a 70 47 6f 62 62 6c 65 20 3d  ntPtr *pGobble =
24890 20 26 6d 65 72 67 65 77 6f 72 6b 65 72 2e 70 43   &mergeworker.pC
248a0 73 72 2d 3e 61 50 74 72 5b 69 5d 3b 0a 20 20 20  sr->aPtr[i];.   
248b0 20 20 20 20 20 20 20 20 20 69 66 28 20 70 47 6f           if( pGo
248c0 62 62 6c 65 2d 3e 70 53 65 67 2d 3e 69 52 6f 6f  bble->pSeg->iRoo
248d0 74 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  t ){.           
248e0 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64 42 74     rc = sortedBt
248f0 72 65 65 47 6f 62 62 6c 65 28 70 44 62 2c 20 6d  reeGobble(pDb, m
24900 65 72 67 65 77 6f 72 6b 65 72 2e 70 43 73 72 2c  ergeworker.pCsr,
24910 20 69 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20   i);.           
24920 20 7d 65 6c 73 65 20 69 66 28 20 6d 65 72 67 65   }else if( merge
24930 77 6f 72 6b 65 72 2e 61 47 6f 62 62 6c 65 5b 69  worker.aGobble[i
24940 5d 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  ] ){.           
24950 20 20 20 6c 73 6d 46 73 47 6f 62 62 6c 65 28 70     lsmFsGobble(p
24960 44 62 2c 20 70 47 6f 62 62 6c 65 2d 3e 70 53 65  Db, pGobble->pSe
24970 67 2c 20 26 6d 65 72 67 65 77 6f 72 6b 65 72 2e  g, &mergeworker.
24980 61 47 6f 62 62 6c 65 5b 69 5d 2c 20 31 29 3b 0a  aGobble[i], 1);.
24990 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20              }.  
249a0 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
249b0 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
249c0 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20     int i;.      
249d0 20 20 20 20 69 6e 74 20 62 45 6d 70 74 79 3b 0a      int bEmpty;.
249e0 20 20 20 20 20 20 20 20 20 20 6d 65 72 67 65 57            mergeW
249f0 6f 72 6b 65 72 53 68 75 74 64 6f 77 6e 28 26 6d  orkerShutdown(&m
24a00 65 72 67 65 77 6f 72 6b 65 72 2c 20 26 72 63 29  ergeworker, &rc)
24a10 3b 0a 20 20 20 20 20 20 20 20 20 20 62 45 6d 70  ;.          bEmp
24a20 74 79 20 3d 20 28 70 4c 65 76 65 6c 2d 3e 6c 68  ty = (pLevel->lh
24a30 73 2e 69 46 69 72 73 74 3d 3d 30 29 3b 0a 0a 20  s.iFirst==0);.. 
24a40 20 20 20 20 20 20 20 20 20 69 66 28 20 62 45 6d           if( bEm
24a50 70 74 79 3d 3d 30 20 26 26 20 72 63 3d 3d 4c 53  pty==0 && rc==LS
24a60 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  M_OK ){.        
24a70 20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 53 6f      rc = lsmFsSo
24a80 72 74 65 64 46 69 6e 69 73 68 28 70 44 62 2d 3e  rtedFinish(pDb->
24a90 70 46 53 2c 20 26 70 4c 65 76 65 6c 2d 3e 6c 68  pFS, &pLevel->lh
24aa0 73 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  s);.          }.
24ab0 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 70  .          if( p
24ac0 44 62 2d 3e 62 55 73 65 46 72 65 65 6c 69 73 74  Db->bUseFreelist
24ad0 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
24ae0 46 72 65 65 6c 69 73 74 20 2a 70 20 3d 20 26 70  Freelist *p = &p
24af0 44 62 2d 3e 70 57 6f 72 6b 65 72 2d 3e 66 72 65  Db->pWorker->fre
24b00 65 6c 69 73 74 3b 0a 20 20 20 20 20 20 20 20 20  elist;.         
24b10 20 20 20 6c 73 6d 46 72 65 65 28 70 44 62 2d 3e     lsmFree(pDb->
24b20 70 45 6e 76 2c 20 70 2d 3e 61 45 6e 74 72 79 29  pEnv, p->aEntry)
24b30 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 65  ;.            me
24b40 6d 63 70 79 28 70 2c 20 26 66 72 65 65 6c 69 73  mcpy(p, &freelis
24b50 74 2c 20 73 69 7a 65 6f 66 28 66 72 65 65 6c 69  t, sizeof(freeli
24b60 73 74 29 29 3b 0a 20 20 20 20 20 20 20 20 20 20  st));.          
24b70 20 20 70 44 62 2d 3e 62 55 73 65 46 72 65 65 6c    pDb->bUseFreel
24b80 69 73 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ist = 0;.       
24b90 20 20 20 20 20 70 44 62 2d 3e 70 46 72 65 65 6c       pDb->pFreel
24ba0 69 73 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ist = 0;.       
24bb0 20 20 20 20 20 62 53 61 76 65 20 3d 20 31 3b 0a       bSave = 1;.
24bc0 20 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20            }..   
24bd0 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20         for(i=0; 
24be0 69 3c 70 4c 65 76 65 6c 2d 3e 6e 52 69 67 68 74  i<pLevel->nRight
24bf0 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
24c00 20 20 20 20 6c 73 6d 46 73 53 6f 72 74 65 64 44      lsmFsSortedD
24c10 65 6c 65 74 65 28 70 44 62 2d 3e 70 46 53 2c 20  elete(pDb->pFS, 
24c20 70 57 6f 72 6b 65 72 2c 20 31 2c 20 26 70 4c 65  pWorker, 1, &pLe
24c30 76 65 6c 2d 3e 61 52 68 73 5b 69 5d 29 3b 0a 20  vel->aRhs[i]);. 
24c40 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20           }..    
24c50 20 20 20 20 20 20 69 66 28 20 62 45 6d 70 74 79        if( bEmpty
24c60 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
24c70 2f 2a 20 49 66 20 74 68 65 20 6e 65 77 20 6c 65  /* If the new le
24c80 76 65 6c 20 69 73 20 63 6f 6d 70 6c 65 74 65 6c  vel is completel
24c90 79 20 65 6d 70 74 79 2c 20 72 65 6d 6f 76 65 20  y empty, remove 
24ca0 69 74 20 66 72 6f 6d 20 74 68 65 20 0a 20 20 20  it from the .   
24cb0 20 20 20 20 20 20 20 20 20 2a 2a 20 64 61 74 61           ** data
24cc0 62 61 73 65 20 73 6e 61 70 73 68 6f 74 2e 20 54  base snapshot. T
24cd0 68 69 73 20 63 61 6e 20 6f 6e 6c 79 20 68 61 70  his can only hap
24ce0 70 65 6e 20 69 66 20 61 6c 6c 20 69 6e 70 75 74  pen if all input
24cf0 20 6b 65 79 73 20 77 65 72 65 0a 20 20 20 20 20   keys were.     
24d00 20 20 20 20 20 20 20 2a 2a 20 61 6e 6e 69 68 69         ** annihi
24d10 6c 61 74 65 64 2e 20 53 69 6e 63 65 20 6b 65 79  lated. Since key
24d20 73 20 61 72 65 20 6f 6e 6c 79 20 61 6e 6e 69 68  s are only annih
24d30 69 6c 61 74 65 64 20 69 66 20 74 68 65 20 6e 65  ilated if the ne
24d40 77 20 6c 65 76 65 6c 0a 20 20 20 20 20 20 20 20  w level.        
24d50 20 20 20 20 2a 2a 20 69 73 20 74 68 65 20 6c 61      ** is the la
24d60 73 74 20 69 6e 20 74 68 65 20 6c 69 6e 6b 65 64  st in the linked
24d70 20 6c 69 73 74 20 28 63 6f 6e 74 61 69 6e 73 20   list (contains 
24d80 74 68 65 20 6d 6f 73 74 20 61 6e 63 69 65 6e 74  the most ancient
24d90 20 6f 66 0a 20 20 20 20 20 20 20 20 20 20 20 20   of.            
24da0 2a 2a 20 64 61 74 61 62 61 73 65 20 63 6f 6e 74  ** database cont
24db0 65 6e 74 29 2c 20 74 68 69 73 20 67 75 61 72 61  ent), this guara
24dc0 6e 74 65 65 73 20 74 68 61 74 20 70 4c 65 76 65  ntees that pLeve
24dd0 6c 2d 3e 70 4e 65 78 74 3d 3d 30 2e 20 20 2a 2f  l->pNext==0.  */
24de0 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 4c 65   .            Le
24df0 76 65 6c 20 2a 70 54 6f 70 3b 20 20 20 20 20 20  vel *pTop;      
24e00 20 20 20 20 2f 2a 20 54 6f 70 20 6c 65 76 65 6c      /* Top level
24e10 20 6f 66 20 77 6f 72 6b 65 72 20 73 6e 61 70 73   of worker snaps
24e20 68 6f 74 20 2a 2f 0a 20 20 20 20 20 20 20 20 20  hot */.         
24e30 20 20 20 4c 65 76 65 6c 20 2a 2a 70 70 3b 20 20     Level **pp;  
24e40 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 61 64           /* Read
24e50 2f 77 72 69 74 65 20 69 74 65 72 61 74 6f 72 20  /write iterator 
24e60 66 6f 72 20 4c 65 76 65 6c 2e 70 4e 65 78 74 20  for Level.pNext 
24e70 6c 69 73 74 20 2a 2f 0a 0a 20 20 20 20 20 20 20  list */..       
24e80 20 20 20 20 20 61 73 73 65 72 74 28 20 70 4c 65       assert( pLe
24e90 76 65 6c 2d 3e 70 4e 65 78 74 3d 3d 30 20 29 3b  vel->pNext==0 );
24ea0 0a 0a 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ..            /*
24eb0 20 52 65 6d 6f 76 65 20 74 68 65 20 6c 65 76 65   Remove the leve
24ec0 6c 20 66 72 6f 6d 20 74 68 65 20 77 6f 72 6b 65  l from the worke
24ed0 72 20 73 6e 61 70 73 68 6f 74 2e 20 2a 2f 0a 20  r snapshot. */. 
24ee0 20 20 20 20 20 20 20 20 20 20 20 70 54 6f 70 20             pTop 
24ef0 3d 20 6c 73 6d 44 62 53 6e 61 70 73 68 6f 74 4c  = lsmDbSnapshotL
24f00 65 76 65 6c 28 70 57 6f 72 6b 65 72 29 3b 0a 20  evel(pWorker);. 
24f10 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 28 70             for(p
24f20 70 3d 26 70 54 6f 70 3b 20 2a 70 70 21 3d 70 4c  p=&pTop; *pp!=pL
24f30 65 76 65 6c 3b 20 70 70 3d 26 28 28 2a 70 70 29  evel; pp=&((*pp)
24f40 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20 20 20  ->pNext));.     
24f50 20 20 20 20 20 20 20 2a 70 70 20 3d 20 70 4c 65         *pp = pLe
24f60 76 65 6c 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  vel->pNext;.    
24f70 20 20 20 20 20 20 20 20 6c 73 6d 44 62 53 6e 61          lsmDbSna
24f80 70 73 68 6f 74 53 65 74 4c 65 76 65 6c 28 70 57  pshotSetLevel(pW
24f90 6f 72 6b 65 72 2c 20 70 54 6f 70 29 3b 0a 0a 20  orker, pTop);.. 
24fa0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72             /* Fr
24fb0 65 65 20 74 68 65 20 4c 65 76 65 6c 20 73 74 72  ee the Level str
24fc0 75 63 74 75 72 65 2e 20 2a 2f 0a 20 20 20 20 20  ucture. */.     
24fd0 20 20 20 20 20 20 20 73 6f 72 74 65 64 46 72 65         sortedFre
24fe0 65 4c 65 76 65 6c 28 70 44 62 2d 3e 70 45 6e 76  eLevel(pDb->pEnv
24ff0 2c 20 70 4c 65 76 65 6c 29 3b 0a 20 20 20 20 20  , pLevel);.     
25000 20 20 20 20 20 7d 65 6c 73 65 7b 0a 0a 20 20 20       }else{..   
25010 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72 65 65           /* Free
25020 20 74 68 65 20 73 65 70 61 72 61 74 6f 72 73 20   the separators 
25030 6f 66 20 74 68 65 20 6e 65 78 74 20 6c 65 76 65  of the next leve
25040 6c 2c 20 69 66 20 72 65 71 75 69 72 65 64 2e 20  l, if required. 
25050 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  */.            i
25060 66 28 20 70 4c 65 76 65 6c 2d 3e 70 4d 65 72 67  f( pLevel->pMerg
25070 65 2d 3e 6e 49 6e 70 75 74 20 3e 20 70 4c 65 76  e->nInput > pLev
25080 65 6c 2d 3e 6e 52 69 67 68 74 20 29 7b 0a 20 20  el->nRight ){.  
25090 20 20 20 20 20 20 20 20 20 20 20 20 61 73 73 65              asse
250a0 72 74 28 20 70 4c 65 76 65 6c 2d 3e 70 4e 65 78  rt( pLevel->pNex
250b0 74 2d 3e 6c 68 73 2e 69 52 6f 6f 74 20 29 3b 0a  t->lhs.iRoot );.
250c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 4c                pL
250d0 65 76 65 6c 2d 3e 70 4e 65 78 74 2d 3e 6c 68 73  evel->pNext->lhs
250e0 2e 69 52 6f 6f 74 20 3d 20 30 3b 0a 20 20 20 20  .iRoot = 0;.    
250f0 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
25100 20 20 20 20 20 20 20 2f 2a 20 5a 65 72 6f 20 74         /* Zero t
25110 68 65 20 72 69 67 68 74 2d 68 61 6e 64 2d 73 69  he right-hand-si
25120 64 65 20 6f 66 20 70 4c 65 76 65 6c 20 2a 2f 0a  de of pLevel */.
25130 20 20 20 20 20 20 20 20 20 20 20 20 6c 73 6d 46              lsmF
25140 72 65 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70  ree(pDb->pEnv, p
25150 4c 65 76 65 6c 2d 3e 61 52 68 73 29 3b 0a 20 20  Level->aRhs);.  
25160 20 20 20 20 20 20 20 20 20 20 70 4c 65 76 65 6c            pLevel
25170 2d 3e 6e 52 69 67 68 74 20 3d 20 30 3b 0a 20 20  ->nRight = 0;.  
25180 20 20 20 20 20 20 20 20 20 20 70 4c 65 76 65 6c            pLevel
25190 2d 3e 61 52 68 73 20 3d 20 30 3b 0a 0a 20 20 20  ->aRhs = 0;..   
251a0 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72 65 65           /* Free
251b0 20 74 68 65 20 4d 65 72 67 65 20 6f 62 6a 65 63   the Merge objec
251c0 74 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 20  t */.           
251d0 20 6c 73 6d 46 72 65 65 28 70 44 62 2d 3e 70 45   lsmFree(pDb->pE
251e0 6e 76 2c 20 70 4c 65 76 65 6c 2d 3e 70 4d 65 72  nv, pLevel->pMer
251f0 67 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  ge);.           
25200 20 70 4c 65 76 65 6c 2d 3e 70 4d 65 72 67 65 20   pLevel->pMerge 
25210 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  = 0;.          }
25220 0a 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ..          if( 
25230 62 53 61 76 65 20 26 26 20 72 63 3d 3d 4c 53 4d  bSave && rc==LSM
25240 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20  _OK ){.         
25250 20 20 20 70 44 62 2d 3e 62 49 6e 63 72 4d 65 72     pDb->bIncrMer
25260 67 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  ge = 0;.        
25270 20 20 20 20 72 63 20 3d 20 6c 73 6d 53 61 76 65      rc = lsmSave
25280 57 6f 72 6b 65 72 28 70 44 62 2c 20 30 29 3b 0a  Worker(pDb, 0);.
25290 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
252a0 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20      }.      }.. 
252b0 20 20 20 20 20 2f 2a 20 43 6c 65 61 6e 20 75 70       /* Clean up
252c0 20 74 68 65 20 4d 65 72 67 65 57 6f 72 6b 65 72   the MergeWorker
252d0 20 6f 62 6a 65 63 74 20 69 6e 69 74 69 61 6c 69   object initiali
252e0 7a 65 64 20 61 62 6f 76 65 2e 20 49 66 20 6e 6f  zed above. If no
252f0 20 65 72 72 6f 72 0a 20 20 20 20 20 20 2a 2a 20   error.      ** 
25300 68 61 73 20 6f 63 63 75 72 72 65 64 2c 20 69 6e  has occurred, in
25310 76 6f 6b 65 20 74 68 65 20 77 6f 72 6b 2d 68 6f  voke the work-ho
25320 6f 6b 20 74 6f 20 69 6e 66 6f 72 6d 20 74 68 65  ok to inform the
25330 20 61 70 70 6c 69 63 61 74 69 6f 6e 20 74 68 61   application tha
25340 74 0a 20 20 20 20 20 20 2a 2a 20 74 68 65 20 64  t.      ** the d
25350 61 74 61 62 61 73 65 20 73 74 72 75 63 74 75 72  atabase structur
25360 65 20 68 61 73 20 63 68 61 6e 67 65 64 2e 20 2a  e has changed. *
25370 2f 0a 20 20 20 20 20 20 6d 65 72 67 65 57 6f 72  /.      mergeWor
25380 6b 65 72 53 68 75 74 64 6f 77 6e 28 26 6d 65 72  kerShutdown(&mer
25390 67 65 77 6f 72 6b 65 72 2c 20 26 72 63 29 3b 0a  geworker, &rc);.
253a0 20 20 20 20 20 20 70 44 62 2d 3e 62 49 6e 63 72        pDb->bIncr
253b0 4d 65 72 67 65 20 3d 20 30 3b 0a 20 20 20 20 20  Merge = 0;.     
253c0 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
253d0 29 20 73 6f 72 74 65 64 49 6e 76 6f 6b 65 57 6f  ) sortedInvokeWo
253e0 72 6b 48 6f 6f 6b 28 70 44 62 29 3b 0a 0a 23 69  rkHook(pDb);..#i
253f0 66 20 4c 53 4d 5f 4c 4f 47 5f 53 54 52 55 43 54  f LSM_LOG_STRUCT
25400 55 52 45 0a 20 20 20 20 20 20 6c 73 6d 53 6f 72  URE.      lsmSor
25410 74 65 64 44 75 6d 70 53 74 72 75 63 74 75 72 65  tedDumpStructure
25420 28 70 44 62 2c 20 70 44 62 2d 3e 70 57 6f 72 6b  (pDb, pDb->pWork
25430 65 72 2c 20 4c 53 4d 5f 4c 4f 47 5f 44 41 54 41  er, LSM_LOG_DATA
25440 2c 20 30 2c 20 22 77 6f 72 6b 22 29 3b 0a 23 65  , 0, "work");.#e
25450 6e 64 69 66 0a 20 20 20 20 20 20 61 73 73 65 72  ndif.      asser
25460 74 42 74 72 65 65 4f 6b 28 70 44 62 2c 20 26 70  tBtreeOk(pDb, &p
25470 4c 65 76 65 6c 2d 3e 6c 68 73 29 3b 0a 20 20 20  Level->lhs);.   
25480 20 20 20 61 73 73 65 72 74 52 75 6e 49 6e 4f 72     assertRunInOr
25490 64 65 72 28 70 44 62 2c 20 26 70 4c 65 76 65 6c  der(pDb, &pLevel
254a0 2d 3e 6c 68 73 29 3b 0a 0a 20 20 20 20 20 20 2f  ->lhs);..      /
254b0 2a 20 49 66 20 62 46 6c 75 73 68 20 69 73 20 74  * If bFlush is t
254c0 72 75 65 20 61 6e 64 20 74 68 65 20 64 61 74 61  rue and the data
254d0 62 61 73 65 20 69 73 20 6e 6f 20 6c 6f 6e 67 65  base is no longe
254e0 72 20 63 6f 6e 73 69 64 65 72 65 64 20 22 66 75  r considered "fu
254f0 6c 6c 22 2c 0a 20 20 20 20 20 20 2a 2a 20 62 72  ll",.      ** br
25500 65 61 6b 20 6f 75 74 20 6f 66 20 74 68 65 20 6c  eak out of the l
25510 6f 6f 70 20 65 76 65 6e 20 69 66 20 6e 52 65 6d  oop even if nRem
25520 61 69 6e 69 6e 67 20 69 73 20 73 74 69 6c 6c 20  aining is still 
25530 67 72 65 61 74 65 72 20 74 68 61 6e 0a 20 20 20  greater than.   
25540 20 20 20 2a 2a 20 7a 65 72 6f 2e 20 54 68 65 20     ** zero. The 
25550 63 61 6c 6c 65 72 20 68 61 73 20 61 6e 20 69 6e  caller has an in
25560 2d 6d 65 6d 6f 72 79 20 74 72 65 65 20 74 6f 20  -memory tree to 
25570 66 6c 75 73 68 20 74 6f 20 64 69 73 6b 2e 20 20  flush to disk.  
25580 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 62 46 6c  */.      if( bFl
25590 75 73 68 20 26 26 20 73 6f 72 74 65 64 44 62 49  ush && sortedDbI
255a0 73 46 75 6c 6c 28 70 44 62 29 3d 3d 30 20 29 20  sFull(pDb)==0 ) 
255b0 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d  break;.    }.  }
255c0 0a 0a 20 20 69 66 28 20 70 6e 57 72 69 74 65 20  ..  if( pnWrite 
255d0 29 20 2a 70 6e 57 72 69 74 65 20 3d 20 28 6e 57  ) *pnWrite = (nW
255e0 6f 72 6b 20 2d 20 6e 52 65 6d 61 69 6e 69 6e 67  ork - nRemaining
255f0 29 3b 0a 20 20 70 57 6f 72 6b 65 72 2d 3e 6e 57  );.  pWorker->nW
25600 72 69 74 65 20 2b 3d 20 28 6e 57 6f 72 6b 20 2d  rite += (nWork -
25610 20 6e 52 65 6d 61 69 6e 69 6e 67 29 3b 0a 0a 23   nRemaining);..#
25620 69 66 64 65 66 20 4c 53 4d 5f 4c 4f 47 5f 57 4f  ifdef LSM_LOG_WO
25630 52 4b 0a 20 20 6c 73 6d 4c 6f 67 4d 65 73 73 61  RK.  lsmLogMessa
25640 67 65 28 70 44 62 2c 20 72 63 2c 20 22 73 6f 72  ge(pDb, rc, "sor
25650 74 65 64 57 6f 72 6b 28 29 3a 20 25 64 20 70 61  tedWork(): %d pa
25660 67 65 73 22 2c 20 28 6e 57 6f 72 6b 2d 6e 52 65  ges", (nWork-nRe
25670 6d 61 69 6e 69 6e 67 29 29 3b 0a 23 65 6e 64 69  maining));.#endi
25680 66 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  f.  return rc;.}
25690 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 64 61 74 61  ../*.** The data
256a0 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  base connection 
256b0 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69  passed as the fi
256c0 72 73 74 20 61 72 67 75 6d 65 6e 74 20 6d 75 73  rst argument mus
256d0 74 20 62 65 20 61 20 77 6f 72 6b 65 72 0a 2a 2a  t be a worker.**
256e0 20 63 6f 6e 6e 65 63 74 69 6f 6e 2e 20 54 68 69   connection. Thi
256f0 73 20 66 75 6e 63 74 69 6f 6e 20 63 68 65 63 6b  s function check
25700 73 20 69 66 20 74 68 65 72 65 20 65 78 69 73 74  s if there exist
25710 73 20 61 6e 20 22 6f 6c 64 22 20 69 6e 2d 6d 65  s an "old" in-me
25720 6d 6f 72 79 20 74 72 65 65 0a 2a 2a 20 72 65 61  mory tree.** rea
25730 64 79 20 74 6f 20 62 65 20 66 6c 75 73 68 65 64  dy to be flushed
25740 20 74 6f 20 64 69 73 6b 2e 20 49 66 20 73 6f 2c   to disk. If so,
25750 20 74 72 75 65 20 69 73 20 72 65 74 75 72 6e 65   true is returne
25760 64 2e 20 4f 74 68 65 72 77 69 73 65 20 66 61 6c  d. Otherwise fal
25770 73 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20  se..**.** If an 
25780 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 2a 70  error occurs, *p
25790 52 63 20 69 73 20 73 65 74 20 74 6f 20 61 6e 20  Rc is set to an 
257a0 4c 53 4d 20 65 72 72 6f 72 20 63 6f 64 65 20 62  LSM error code b
257b0 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
257c0 0a 2a 2a 20 49 74 20 69 73 20 61 73 73 75 6d 65  .** It is assume
257d0 64 20 74 68 61 74 20 2a 70 52 63 20 69 73 20 73  d that *pRc is s
257e0 65 74 20 74 6f 20 4c 53 4d 5f 4f 4b 20 77 68 65  et to LSM_OK whe
257f0 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
25800 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74  is called..*/.st
25810 61 74 69 63 20 69 6e 74 20 73 6f 72 74 65 64 54  atic int sortedT
25820 72 65 65 48 61 73 4f 6c 64 28 6c 73 6d 5f 64 62  reeHasOld(lsm_db
25830 20 2a 70 44 62 2c 20 69 6e 74 20 2a 70 52 63 29   *pDb, int *pRc)
25840 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d  {.  int rc = LSM
25850 5f 4f 4b 3b 0a 20 20 69 6e 74 20 62 52 65 74 20  _OK;.  int bRet 
25860 3d 20 30 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  = 0;..  assert( 
25870 70 44 62 2d 3e 70 57 6f 72 6b 65 72 20 29 3b 0a  pDb->pWorker );.
25880 20 20 69 66 28 20 2a 70 52 63 3d 3d 4c 53 4d 5f    if( *pRc==LSM_
25890 4f 4b 20 29 7b 0a 20 20 20 20 69 66 28 20 72 63  OK ){.    if( rc
258a0 3d 3d 4c 53 4d 5f 4f 4b 20 0a 20 20 20 20 20 20  ==LSM_OK .      
258b0 20 20 26 26 20 70 44 62 2d 3e 74 72 65 65 68 64    && pDb->treehd
258c0 72 2e 69 4f 6c 64 53 68 6d 69 64 0a 20 20 20 20  r.iOldShmid.    
258d0 20 20 20 20 26 26 20 70 44 62 2d 3e 74 72 65 65      && pDb->tree
258e0 68 64 72 2e 69 4f 6c 64 4c 6f 67 21 3d 70 44 62  hdr.iOldLog!=pDb
258f0 2d 3e 70 57 6f 72 6b 65 72 2d 3e 69 4c 6f 67 4f  ->pWorker->iLogO
25900 66 66 20 0a 20 20 20 20 20 20 29 7b 0a 20 20 20  ff .      ){.   
25910 20 20 20 62 52 65 74 20 3d 20 31 3b 0a 20 20 20     bRet = 1;.   
25920 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 62 52   }else{.      bR
25930 65 74 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20  et = 0;.    }.  
25940 20 20 2a 70 52 63 20 3d 20 72 63 3b 0a 20 20 7d    *pRc = rc;.  }
25950 0a 20 20 61 73 73 65 72 74 28 20 2a 70 52 63 3d  .  assert( *pRc=
25960 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 62 52 65 74 3d  =LSM_OK || bRet=
25970 3d 30 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 62  =0 );.  return b
25980 52 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72  Ret;.}../*.** Cr
25990 65 61 74 65 20 61 20 6e 65 77 20 66 72 65 65 2d  eate a new free-
259a0 6c 69 73 74 20 6f 6e 6c 79 20 74 6f 70 2d 6c 65  list only top-le
259b0 76 65 6c 20 73 65 67 6d 65 6e 74 2e 20 52 65 74  vel segment. Ret
259c0 75 72 6e 20 4c 53 4d 5f 4f 4b 20 69 66 20 73 75  urn LSM_OK if su
259d0 63 63 65 73 73 66 75 6c 0a 2a 2a 20 6f 72 20 61  ccessful.** or a
259e0 6e 20 4c 53 4d 20 65 72 72 6f 72 20 63 6f 64 65  n LSM error code
259f0 20 69 66 20 73 6f 6d 65 20 65 72 72 6f 72 20 6f   if some error o
25a00 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  ccurs..*/.static
25a10 20 69 6e 74 20 73 6f 72 74 65 64 4e 65 77 46 72   int sortedNewFr
25a20 65 65 6c 69 73 74 4f 6e 6c 79 28 6c 73 6d 5f 64  eelistOnly(lsm_d
25a30 62 20 2a 70 44 62 29 7b 0a 20 20 72 65 74 75 72  b *pDb){.  retur
25a40 6e 20 73 6f 72 74 65 64 4e 65 77 54 6f 70 6c 65  n sortedNewTople
25a50 76 65 6c 28 70 44 62 2c 20 54 52 45 45 5f 4e 4f  vel(pDb, TREE_NO
25a60 4e 45 2c 20 30 29 3b 0a 7d 0a 0a 69 6e 74 20 6c  NE, 0);.}..int l
25a70 73 6d 53 61 76 65 57 6f 72 6b 65 72 28 6c 73 6d  smSaveWorker(lsm
25a80 5f 64 62 20 2a 70 44 62 2c 20 69 6e 74 20 62 46  _db *pDb, int bF
25a90 6c 75 73 68 29 7b 0a 20 20 53 6e 61 70 73 68 6f  lush){.  Snapsho
25aa0 74 20 2a 70 20 3d 20 70 44 62 2d 3e 70 57 6f 72  t *p = pDb->pWor
25ab0 6b 65 72 3b 0a 20 20 69 66 28 20 70 2d 3e 66 72  ker;.  if( p->fr
25ac0 65 65 6c 69 73 74 2e 6e 45 6e 74 72 79 3e 70 44  eelist.nEntry>pD
25ad0 62 2d 3e 6e 4d 61 78 46 72 65 65 6c 69 73 74 20  b->nMaxFreelist 
25ae0 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20  ){.    int rc = 
25af0 73 6f 72 74 65 64 4e 65 77 46 72 65 65 6c 69 73  sortedNewFreelis
25b00 74 4f 6e 6c 79 28 70 44 62 29 3b 0a 20 20 20 20  tOnly(pDb);.    
25b10 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29  if( rc!=LSM_OK )
25b20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
25b30 20 20 72 65 74 75 72 6e 20 6c 73 6d 43 68 65 63    return lsmChec
25b40 6b 70 6f 69 6e 74 53 61 76 65 57 6f 72 6b 65 72  kpointSaveWorker
25b50 28 70 44 62 2c 20 62 46 6c 75 73 68 29 3b 0a 7d  (pDb, bFlush);.}
25b60 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 64 6f 4c  ..static int doL
25b70 73 6d 53 69 6e 67 6c 65 57 6f 72 6b 28 0a 20 20  smSingleWork(.  
25b80 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 0a 20 20  lsm_db *pDb, .  
25b90 69 6e 74 20 62 53 68 75 74 64 6f 77 6e 2c 0a 20  int bShutdown,. 
25ba0 20 69 6e 74 20 6e 4d 65 72 67 65 2c 20 20 20 20   int nMerge,    
25bb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25bc0 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 73 65 67 6d   /* Minimum segm
25bd0 65 6e 74 73 20 74 6f 20 6d 65 72 67 65 20 74 6f  ents to merge to
25be0 67 65 74 68 65 72 20 2a 2f 0a 20 20 69 6e 74 20  gether */.  int 
25bf0 6e 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20  nPage,          
25c00 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
25c10 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 74  umber of pages t
25c20 6f 20 77 72 69 74 65 20 74 6f 20 64 69 73 6b 20  o write to disk 
25c30 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 57 72 69 74  */.  int *pnWrit
25c40 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
25c50 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50 61 67       /* OUT: Pag
25c60 65 73 20 61 63 74 75 61 6c 6c 79 20 77 72 69 74  es actually writ
25c70 74 65 6e 20 74 6f 20 64 69 73 6b 20 2a 2f 0a 20  ten to disk */. 
25c80 20 69 6e 74 20 2a 70 62 43 6b 70 74 20 20 20 20   int *pbCkpt    
25c90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25ca0 20 2f 2a 20 4f 55 54 3a 20 54 72 75 65 20 69 66   /* OUT: True if
25cb0 20 61 6e 20 61 75 74 6f 2d 63 68 65 63 6b 70 6f   an auto-checkpo
25cc0 69 6e 74 20 69 73 20 72 65 71 2e 20 2a 2f 0a 29  int is req. */.)
25cd0 7b 0a 20 20 53 6e 61 70 73 68 6f 74 20 2a 70 57  {.  Snapshot *pW
25ce0 6f 72 6b 65 72 3b 20 20 20 20 20 20 20 20 20 20  orker;          
25cf0 20 20 20 20 2f 2a 20 57 6f 72 6b 65 72 20 73 6e      /* Worker sn
25d00 61 70 73 68 6f 74 20 2a 2f 0a 20 20 69 6e 74 20  apshot */.  int 
25d10 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20  rc = LSM_OK;    
25d20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
25d30 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
25d40 69 6e 74 20 62 44 69 72 74 79 20 3d 20 30 3b 0a  int bDirty = 0;.
25d50 20 20 69 6e 74 20 6e 4d 61 78 20 3d 20 6e 50 61    int nMax = nPa
25d60 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
25d70 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 70 61 67    /* Maximum pag
25d80 65 73 20 74 6f 20 77 72 69 74 65 20 74 6f 20 64  es to write to d
25d90 69 73 6b 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65  isk */.  int nRe
25da0 6d 20 3d 20 6e 50 61 67 65 3b 0a 20 20 69 6e 74  m = nPage;.  int
25db0 20 62 43 6b 70 74 20 3d 20 30 3b 0a 0a 20 20 61   bCkpt = 0;..  a
25dc0 73 73 65 72 74 28 20 6e 50 61 67 65 3e 30 20 29  ssert( nPage>0 )
25dd0 3b 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 74 68 65  ;..  /* Open the
25de0 20 77 6f 72 6b 65 72 20 27 74 72 61 6e 73 61 63   worker 'transac
25df0 74 69 6f 6e 27 2e 20 49 74 20 77 69 6c 6c 20 62  tion'. It will b
25e00 65 20 63 6c 6f 73 65 64 20 62 65 66 6f 72 65 20  e closed before 
25e10 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 0a 20 20  this function.  
25e20 2a 2a 20 72 65 74 75 72 6e 73 2e 20 20 2a 2f 0a  ** returns.  */.
25e30 20 20 61 73 73 65 72 74 28 20 70 44 62 2d 3e 70    assert( pDb->p
25e40 57 6f 72 6b 65 72 3d 3d 30 20 29 3b 0a 20 20 72  Worker==0 );.  r
25e50 63 20 3d 20 6c 73 6d 42 65 67 69 6e 57 6f 72 6b  c = lsmBeginWork
25e60 28 70 44 62 29 3b 0a 20 20 69 66 28 20 72 63 21  (pDb);.  if( rc!
25e70 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65 74 75 72 6e  =LSM_OK ) return
25e80 20 72 63 3b 0a 20 20 70 57 6f 72 6b 65 72 20 3d   rc;.  pWorker =
25e90 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 3b 0a 0a   pDb->pWorker;..
25ea0 20 20 2f 2a 20 49 66 20 74 68 69 73 20 63 6f 6e    /* If this con
25eb0 6e 65 63 74 69 6f 6e 20 69 73 20 64 6f 69 6e 67  nection is doing
25ec0 20 61 75 74 6f 2d 63 68 65 63 6b 70 6f 69 6e 74   auto-checkpoint
25ed0 73 2c 20 73 65 74 20 6e 4d 61 78 20 28 61 6e 64  s, set nMax (and
25ee0 20 6e 52 65 6d 29 20 73 6f 0a 20 20 2a 2a 20 74   nRem) so.  ** t
25ef0 68 61 74 20 74 68 69 73 20 63 61 6c 6c 20 73 74  hat this call st
25f00 6f 70 73 20 77 72 69 74 69 6e 67 20 77 68 65 6e  ops writing when
25f10 20 74 68 65 20 61 75 74 6f 2d 63 68 65 63 6b 70   the auto-checkp
25f20 6f 69 6e 74 20 69 73 20 64 75 65 2e 20 54 68 65  oint is due. The
25f30 0a 20 20 2a 2a 20 63 61 6c 6c 65 72 20 77 69 6c  .  ** caller wil
25f40 6c 20 64 6f 20 74 68 65 20 63 68 65 63 6b 70 6f  l do the checkpo
25f50 69 6e 74 2c 20 74 68 65 6e 20 70 6f 73 73 69 62  int, then possib
25f60 6c 79 20 63 61 6c 6c 20 74 68 69 73 20 66 75 6e  ly call this fun
25f70 63 74 69 6f 6e 20 61 67 61 69 6e 2e 20 2a 2f 0a  ction again. */.
25f80 20 20 69 66 28 20 62 53 68 75 74 64 6f 77 6e 3d    if( bShutdown=
25f90 3d 30 20 26 26 20 70 44 62 2d 3e 6e 41 75 74 6f  =0 && pDb->nAuto
25fa0 63 6b 70 74 20 29 7b 0a 20 20 20 20 75 33 32 20  ckpt ){.    u32 
25fb0 6e 53 79 6e 63 3b 0a 20 20 20 20 75 33 32 20 6e  nSync;.    u32 n
25fc0 55 6e 73 79 6e 63 3b 0a 20 20 20 20 69 6e 74 20  Unsync;.    int 
25fd0 6e 50 67 73 7a 3b 0a 0a 20 20 20 20 6c 73 6d 43  nPgsz;..    lsmC
25fe0 68 65 63 6b 70 6f 69 6e 74 53 79 6e 63 65 64 28  heckpointSynced(
25ff0 70 44 62 2c 20 30 2c 20 30 2c 20 26 6e 53 79 6e  pDb, 0, 0, &nSyn
26000 63 29 3b 0a 20 20 20 20 6e 55 6e 73 79 6e 63 20  c);.    nUnsync 
26010 3d 20 6c 73 6d 43 68 65 63 6b 70 6f 69 6e 74 4e  = lsmCheckpointN
26020 57 72 69 74 65 28 70 44 62 2d 3e 70 53 68 6d 68  Write(pDb->pShmh
26030 64 72 2d 3e 61 53 6e 61 70 31 2c 20 30 29 3b 0a  dr->aSnap1, 0);.
26040 20 20 20 20 6e 50 67 73 7a 20 3d 20 6c 73 6d 43      nPgsz = lsmC
26050 68 65 63 6b 70 6f 69 6e 74 50 67 73 7a 28 70 44  heckpointPgsz(pD
26060 62 2d 3e 70 53 68 6d 68 64 72 2d 3e 61 53 6e 61  b->pShmhdr->aSna
26070 70 31 29 3b 0a 0a 20 20 20 20 6e 4d 61 78 20 3d  p1);..    nMax =
26080 20 4c 53 4d 5f 4d 49 4e 28 6e 4d 61 78 2c 20 28   LSM_MIN(nMax, (
26090 70 44 62 2d 3e 6e 41 75 74 6f 63 6b 70 74 2f 6e  pDb->nAutockpt/n
260a0 50 67 73 7a 29 20 2d 20 28 69 6e 74 29 28 6e 55  Pgsz) - (int)(nU
260b0 6e 73 79 6e 63 2d 6e 53 79 6e 63 29 29 3b 0a 20  nsync-nSync));. 
260c0 20 20 20 69 66 28 20 6e 4d 61 78 3c 6e 52 65 6d     if( nMax<nRem
260d0 20 29 7b 0a 20 20 20 20 20 20 62 43 6b 70 74 20   ){.      bCkpt 
260e0 3d 20 31 3b 0a 20 20 20 20 20 20 6e 52 65 6d 20  = 1;.      nRem 
260f0 3d 20 4c 53 4d 5f 4d 41 58 28 6e 4d 61 78 2c 20  = LSM_MAX(nMax, 
26100 30 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  0);.    }.  }.. 
26110 20 2f 2a 20 49 66 20 74 68 65 72 65 20 65 78 69   /* If there exi
26120 73 74 73 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61  sts in-memory da
26130 74 61 20 72 65 61 64 79 20 74 6f 20 62 65 20 66  ta ready to be f
26140 6c 75 73 68 65 64 20 74 6f 20 64 69 73 6b 2c 20  lushed to disk, 
26150 61 74 74 65 6d 70 74 0a 20 20 2a 2a 20 74 6f 20  attempt.  ** to 
26160 66 6c 75 73 68 20 69 74 20 6e 6f 77 2e 20 20 2a  flush it now.  *
26170 2f 0a 20 20 69 66 28 20 70 44 62 2d 3e 6e 54 72  /.  if( pDb->nTr
26180 61 6e 73 4f 70 65 6e 3d 3d 30 20 29 7b 0a 20 20  ansOpen==0 ){.  
26190 20 20 72 63 20 3d 20 6c 73 6d 54 72 65 65 4c 6f    rc = lsmTreeLo
261a0 61 64 48 65 61 64 65 72 28 70 44 62 2c 20 30 29  adHeader(pDb, 0)
261b0 3b 0a 20 20 7d 0a 20 20 69 66 28 20 73 6f 72 74  ;.  }.  if( sort
261c0 65 64 54 72 65 65 48 61 73 4f 6c 64 28 70 44 62  edTreeHasOld(pDb
261d0 2c 20 26 72 63 29 20 29 7b 0a 20 20 20 20 2f 2a  , &rc) ){.    /*
261e0 20 73 6f 72 74 65 64 44 62 49 73 46 75 6c 6c 28   sortedDbIsFull(
261f0 29 20 72 65 74 75 72 6e 73 20 6e 6f 6e 2d 7a 65  ) returns non-ze
26200 72 6f 20 69 66 20 65 69 74 68 65 72 20 28 61 29  ro if either (a)
26210 20 74 68 65 72 65 20 61 72 65 20 74 6f 6f 20 6d   there are too m
26220 61 6e 79 0a 20 20 20 20 2a 2a 20 6c 65 76 65 6c  any.    ** level
26230 73 20 69 6e 20 74 6f 74 61 6c 20 69 6e 20 74 68  s in total in th
26240 65 20 64 62 2c 20 6f 72 20 28 62 29 20 74 68 65  e db, or (b) the
26250 72 65 20 61 72 65 20 74 6f 6f 20 6d 61 6e 79 20  re are too many 
26260 6c 65 76 65 6c 73 20 77 69 74 68 20 74 68 65 0a  levels with the.
26270 20 20 20 20 2a 2a 20 74 68 65 20 73 61 6d 65 20      ** the same 
26280 61 67 65 20 69 6e 20 74 68 65 20 64 62 2e 20 45  age in the db. E
26290 69 74 68 65 72 20 77 61 79 2c 20 63 61 6c 6c 20  ither way, call 
262a0 73 6f 72 74 65 64 57 6f 72 6b 28 29 20 74 6f 20  sortedWork() to 
262b0 6d 65 72 67 65 20 0a 20 20 20 20 2a 2a 20 65 78  merge .    ** ex
262c0 69 73 74 69 6e 67 20 73 65 67 6d 65 6e 74 73 20  isting segments 
262d0 74 6f 67 65 74 68 65 72 20 75 6e 74 69 6c 20 74  together until t
262e0 68 69 73 20 63 6f 6e 64 69 74 69 6f 6e 20 69 73  his condition is
262f0 20 63 6c 65 61 72 65 64 2e 20 20 2a 2f 0a 20 20   cleared.  */.  
26300 20 20 69 66 28 20 73 6f 72 74 65 64 44 62 49 73    if( sortedDbIs
26310 46 75 6c 6c 28 70 44 62 29 20 29 7b 0a 20 20 20  Full(pDb) ){.   
26320 20 20 20 69 6e 74 20 6e 50 67 20 3d 20 30 3b 0a     int nPg = 0;.
26330 20 20 20 20 20 20 72 63 20 3d 20 73 6f 72 74 65        rc = sorte
26340 64 57 6f 72 6b 28 70 44 62 2c 20 6e 52 65 6d 2c  dWork(pDb, nRem,
26350 20 6e 4d 65 72 67 65 2c 20 31 2c 20 26 6e 50 67   nMerge, 1, &nPg
26360 29 3b 0a 20 20 20 20 20 20 6e 52 65 6d 20 2d 3d  );.      nRem -=
26370 20 6e 50 67 3b 0a 20 20 20 20 20 20 61 73 73 65   nPg;.      asse
26380 72 74 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c  rt( rc!=LSM_OK |
26390 7c 20 6e 52 65 6d 3c 3d 30 20 7c 7c 20 21 73 6f  | nRem<=0 || !so
263a0 72 74 65 64 44 62 49 73 46 75 6c 6c 28 70 44 62  rtedDbIsFull(pDb
263b0 29 20 29 3b 0a 20 20 20 20 20 20 62 44 69 72 74  ) );.      bDirt
263c0 79 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 0a 20 20  y = 1;.    }..  
263d0 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
263e0 20 26 26 20 6e 52 65 6d 3e 30 20 29 7b 0a 20 20   && nRem>0 ){.  
263f0 20 20 20 20 69 6e 74 20 6e 50 67 20 3d 20 30 3b      int nPg = 0;
26400 0a 20 20 20 20 20 20 72 63 20 3d 20 73 6f 72 74  .      rc = sort
26410 65 64 4e 65 77 54 6f 70 6c 65 76 65 6c 28 70 44  edNewToplevel(pD
26420 62 2c 20 54 52 45 45 5f 4f 4c 44 2c 20 26 6e 50  b, TREE_OLD, &nP
26430 67 29 3b 0a 20 20 20 20 20 20 6e 52 65 6d 20 2d  g);.      nRem -
26440 3d 20 6e 50 67 3b 0a 20 20 20 20 20 20 69 66 28  = nPg;.      if(
26450 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20   rc==LSM_OK ){. 
26460 20 20 20 20 20 20 20 69 66 28 20 70 44 62 2d 3e         if( pDb->
26470 6e 54 72 61 6e 73 4f 70 65 6e 3e 30 20 29 7b 0a  nTransOpen>0 ){.
26480 20 20 20 20 20 20 20 20 20 20 6c 73 6d 54 72 65            lsmTre
26490 65 44 69 73 63 61 72 64 4f 6c 64 28 70 44 62 29  eDiscardOld(pDb)
264a0 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
264b0 20 20 20 20 72 63 20 3d 20 6c 73 6d 53 61 76 65      rc = lsmSave
264c0 57 6f 72 6b 65 72 28 70 44 62 2c 20 31 29 3b 0a  Worker(pDb, 1);.
264d0 20 20 20 20 20 20 20 20 62 44 69 72 74 79 20 3d          bDirty =
264e0 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20   0;.      }.    
264f0 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 6e  }.  }..  /* If n
26500 50 61 67 65 20 69 73 20 73 74 69 6c 6c 20 67 72  Page is still gr
26510 65 61 74 65 72 20 74 68 61 6e 20 7a 65 72 6f 2c  eater than zero,
26520 20 64 6f 20 73 6f 6d 65 20 6d 65 72 67 69 6e 67   do some merging
26530 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 4c  . */.  if( rc==L
26540 53 4d 5f 4f 4b 20 26 26 20 6e 52 65 6d 3e 30 20  SM_OK && nRem>0 
26550 26 26 20 62 53 68 75 74 64 6f 77 6e 3d 3d 30 20  && bShutdown==0 
26560 29 7b 0a 20 20 20 20 69 6e 74 20 6e 50 67 20 3d  ){.    int nPg =
26570 20 30 3b 0a 20 20 20 20 72 63 20 3d 20 73 6f 72   0;.    rc = sor
26580 74 65 64 57 6f 72 6b 28 70 44 62 2c 20 6e 52 65  tedWork(pDb, nRe
26590 6d 2c 20 6e 4d 65 72 67 65 2c 20 30 2c 20 26 6e  m, nMerge, 0, &n
265a0 50 67 29 3b 0a 20 20 20 20 6e 52 65 6d 20 2d 3d  Pg);.    nRem -=
265b0 20 6e 50 67 3b 0a 20 20 20 20 69 66 28 20 6e 50   nPg;.    if( nP
265c0 67 20 29 20 62 44 69 72 74 79 20 3d 20 31 3b 0a  g ) bDirty = 1;.
265d0 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65    }..  /* If the
265e0 20 69 6e 2d 6d 65 6d 6f 72 79 20 70 61 72 74 20   in-memory part 
265f0 6f 66 20 74 68 65 20 66 72 65 65 2d 6c 69 73 74  of the free-list
26600 20 69 73 20 74 6f 6f 20 6c 61 72 67 65 2c 20 77   is too large, w
26610 72 69 74 65 20 61 20 6e 65 77 20 0a 20 20 2a 2a  rite a new .  **
26620 20 74 6f 70 2d 6c 65 76 65 6c 20 63 6f 6e 74 61   top-level conta
26630 69 6e 69 6e 67 20 6a 75 73 74 20 74 68 65 20 69  ining just the i
26640 6e 2d 6d 65 6d 6f 72 79 20 66 72 65 65 2d 6c 69  n-memory free-li
26650 73 74 20 65 6e 74 72 69 65 73 20 74 6f 20 64 69  st entries to di
26660 73 6b 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d  sk. */.  if( rc=
26670 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 44 62 2d 3e  =LSM_OK && pDb->
26680 70 57 6f 72 6b 65 72 2d 3e 66 72 65 65 6c 69 73  pWorker->freelis
26690 74 2e 6e 45 6e 74 72 79 20 3e 20 70 44 62 2d 3e  t.nEntry > pDb->
266a0 6e 4d 61 78 46 72 65 65 6c 69 73 74 20 29 7b 0a  nMaxFreelist ){.
266b0 20 20 20 20 69 6e 74 20 6e 50 67 20 3d 20 30 3b      int nPg = 0;
266c0 0a 20 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d  .    while( rc==
266d0 4c 53 4d 5f 4f 4b 20 26 26 20 6c 73 6d 44 61 74  LSM_OK && lsmDat
266e0 61 62 61 73 65 46 75 6c 6c 28 70 44 62 29 20 29  abaseFull(pDb) )
266f0 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 6f 72  {.      rc = sor
26700 74 65 64 57 6f 72 6b 28 70 44 62 2c 20 31 36 2c  tedWork(pDb, 16,
26710 20 6e 4d 65 72 67 65 2c 20 31 2c 20 26 6e 50 67   nMerge, 1, &nPg
26720 29 3b 0a 20 20 20 20 20 20 6e 52 65 6d 20 2d 3d  );.      nRem -=
26730 20 6e 50 67 3b 0a 20 20 20 20 7d 0a 20 20 20 20   nPg;.    }.    
26740 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
26750 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 6f 72  {.      rc = sor
26760 74 65 64 4e 65 77 46 72 65 65 6c 69 73 74 4f 6e  tedNewFreelistOn
26770 6c 79 28 70 44 62 29 3b 0a 20 20 20 20 7d 0a 20  ly(pDb);.    }. 
26780 20 20 20 6e 52 65 6d 20 2d 3d 20 6e 50 67 3b 0a     nRem -= nPg;.
26790 20 20 20 20 69 66 28 20 6e 50 67 20 29 20 62 44      if( nPg ) bD
267a0 69 72 74 79 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20  irty = 1;.  }.. 
267b0 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
267c0 29 7b 0a 20 20 20 20 2a 70 6e 57 72 69 74 65 20  ){.    *pnWrite 
267d0 3d 20 28 6e 4d 61 78 20 2d 20 6e 52 65 6d 29 3b  = (nMax - nRem);
267e0 0a 20 20 20 20 2a 70 62 43 6b 70 74 20 3d 20 28  .    *pbCkpt = (
267f0 62 43 6b 70 74 20 26 26 20 6e 52 65 6d 3c 3d 30  bCkpt && nRem<=0
26800 29 3b 0a 20 20 20 20 69 66 28 20 6e 4d 65 72 67  );.    if( nMerg
26810 65 3d 3d 31 20 26 26 20 70 44 62 2d 3e 6e 41 75  e==1 && pDb->nAu
26820 74 6f 63 6b 70 74 3e 30 20 26 26 20 2a 70 6e 57  tockpt>0 && *pnW
26830 72 69 74 65 3e 30 0a 20 20 20 20 20 26 26 20 70  rite>0.     && p
26840 57 6f 72 6b 65 72 2d 3e 70 4c 65 76 65 6c 20 0a  Worker->pLevel .
26850 20 20 20 20 20 26 26 20 70 57 6f 72 6b 65 72 2d       && pWorker-
26860 3e 70 4c 65 76 65 6c 2d 3e 6e 52 69 67 68 74 3d  >pLevel->nRight=
26870 3d 30 20 0a 20 20 20 20 20 26 26 20 70 57 6f 72  =0 .     && pWor
26880 6b 65 72 2d 3e 70 4c 65 76 65 6c 2d 3e 70 4e 65  ker->pLevel->pNe
26890 78 74 3d 3d 30 20 0a 20 20 20 20 29 7b 0a 20 20  xt==0 .    ){.  
268a0 20 20 20 20 2a 70 62 43 6b 70 74 20 3d 20 31 3b      *pbCkpt = 1;
268b0 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
268c0 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20  ( rc==LSM_OK && 
268d0 62 44 69 72 74 79 20 29 7b 0a 20 20 20 20 6c 73  bDirty ){.    ls
268e0 6d 46 69 6e 69 73 68 57 6f 72 6b 28 70 44 62 2c  mFinishWork(pDb,
268f0 20 30 2c 20 26 72 63 29 3b 0a 20 20 7d 65 6c 73   0, &rc);.  }els
26900 65 7b 0a 20 20 20 20 69 6e 74 20 72 63 64 75 6d  e{.    int rcdum
26910 6d 79 20 3d 20 4c 53 4d 5f 42 55 53 59 3b 0a 20  my = LSM_BUSY;. 
26920 20 20 20 6c 73 6d 46 69 6e 69 73 68 57 6f 72 6b     lsmFinishWork
26930 28 70 44 62 2c 20 30 2c 20 26 72 63 64 75 6d 6d  (pDb, 0, &rcdumm
26940 79 29 3b 0a 20 20 20 20 2a 70 6e 57 72 69 74 65  y);.    *pnWrite
26950 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 61 73 73 65   = 0;.  }.  asse
26960 72 74 28 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72  rt( pDb->pWorker
26970 3d 3d 30 20 29 3b 0a 20 20 72 65 74 75 72 6e 20  ==0 );.  return 
26980 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  rc;.}..static in
26990 74 20 64 6f 4c 73 6d 57 6f 72 6b 28 6c 73 6d 5f  t doLsmWork(lsm_
269a0 64 62 20 2a 70 44 62 2c 20 69 6e 74 20 6e 4d 65  db *pDb, int nMe
269b0 72 67 65 2c 20 69 6e 74 20 6e 50 61 67 65 2c 20  rge, int nPage, 
269c0 69 6e 74 20 2a 70 6e 57 72 69 74 65 29 7b 0a 20  int *pnWrite){. 
269d0 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
269e0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
269f0 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
26a00 2a 2f 0a 20 20 69 6e 74 20 6e 57 72 69 74 65 20  */.  int nWrite 
26a10 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
26a20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
26a30 66 20 70 61 67 65 73 20 77 72 69 74 74 65 6e 20  f pages written 
26a40 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 4d  */..  assert( nM
26a50 65 72 67 65 3e 3d 31 20 29 3b 0a 0a 20 20 69 66  erge>=1 );..  if
26a60 28 20 6e 50 61 67 65 21 3d 30 20 29 7b 0a 20 20  ( nPage!=0 ){.  
26a70 20 20 69 6e 74 20 62 43 6b 70 74 20 3d 20 30 3b    int bCkpt = 0;
26a80 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20 20 20  .    do {.      
26a90 69 6e 74 20 6e 54 68 69 73 20 3d 20 30 3b 0a 20  int nThis = 0;. 
26aa0 20 20 20 20 20 69 6e 74 20 6e 52 65 71 20 3d 20       int nReq = 
26ab0 28 6e 50 61 67 65 3e 3d 30 29 20 3f 20 28 6e 50  (nPage>=0) ? (nP
26ac0 61 67 65 2d 6e 57 72 69 74 65 29 20 3a 20 28 28  age-nWrite) : ((
26ad0 69 6e 74 29 30 78 37 46 46 46 46 46 46 46 29 3b  int)0x7FFFFFFF);
26ae0 0a 0a 20 20 20 20 20 20 62 43 6b 70 74 20 3d 20  ..      bCkpt = 
26af0 30 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 64 6f  0;.      rc = do
26b00 4c 73 6d 53 69 6e 67 6c 65 57 6f 72 6b 28 70 44  LsmSingleWork(pD
26b10 62 2c 20 30 2c 20 6e 4d 65 72 67 65 2c 20 6e 52  b, 0, nMerge, nR
26b20 65 71 2c 20 26 6e 54 68 69 73 2c 20 26 62 43 6b  eq, &nThis, &bCk
26b30 70 74 29 3b 0a 20 20 20 20 20 20 6e 57 72 69 74  pt);.      nWrit
26b40 65 20 2b 3d 20 6e 54 68 69 73 3b 0a 20 20 20 20  e += nThis;.    
26b50 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
26b60 20 26 26 20 62 43 6b 70 74 20 29 7b 0a 20 20 20   && bCkpt ){.   
26b70 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 5f 63 68       rc = lsm_ch
26b80 65 63 6b 70 6f 69 6e 74 28 70 44 62 2c 20 30 29  eckpoint(pDb, 0)
26b90 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 77  ;.      }.    }w
26ba0 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b  hile( rc==LSM_OK
26bb0 20 26 26 20 62 43 6b 70 74 20 26 26 20 28 6e 57   && bCkpt && (nW
26bc0 72 69 74 65 3c 6e 50 61 67 65 20 7c 7c 20 6e 50  rite<nPage || nP
26bd0 61 67 65 3c 30 29 20 29 3b 0a 20 20 7d 0a 0a 20  age<0) );.  }.. 
26be0 20 69 66 28 20 70 6e 57 72 69 74 65 20 29 7b 0a   if( pnWrite ){.
26bf0 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f      if( rc==LSM_
26c00 4f 4b 20 29 7b 0a 20 20 20 20 20 20 2a 70 6e 57  OK ){.      *pnW
26c10 72 69 74 65 20 3d 20 6e 57 72 69 74 65 3b 0a 20  rite = nWrite;. 
26c20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
26c30 2a 70 6e 57 72 69 74 65 20 3d 20 30 3b 0a 20 20  *pnWrite = 0;.  
26c40 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
26c50 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 65   rc;.}../*.** Pe
26c60 72 66 6f 72 6d 20 77 6f 72 6b 20 74 6f 20 6d 65  rform work to me
26c70 72 67 65 20 64 61 74 61 62 61 73 65 20 73 65 67  rge database seg
26c80 6d 65 6e 74 73 20 74 6f 67 65 74 68 65 72 2e 0a  ments together..
26c90 2a 2f 0a 69 6e 74 20 6c 73 6d 5f 77 6f 72 6b 28  */.int lsm_work(
26ca0 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 69 6e 74  lsm_db *pDb, int
26cb0 20 6e 4d 65 72 67 65 2c 20 69 6e 74 20 6e 4b 42   nMerge, int nKB
26cc0 2c 20 69 6e 74 20 2a 70 6e 57 72 69 74 65 29 7b  , int *pnWrite){
26cd0 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
26ce0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26cf0 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
26d00 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 67 73 7a  e */.  int nPgsz
26d10 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
26d20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 6d 69 6e 61         /* Nomina
26d30 6c 20 70 61 67 65 20 73 69 7a 65 20 69 6e 20 62  l page size in b
26d40 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 50  ytes */.  int nP
26d50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  age;            
26d60 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45 71 75            /* Equ
26d70 69 76 61 6c 65 6e 74 20 6f 66 20 6e 4b 42 20 69  ivalent of nKB i
26d80 6e 20 70 61 67 65 73 20 2a 2f 0a 20 20 69 6e 74  n pages */.  int
26d90 20 6e 57 72 69 74 65 20 3d 20 30 3b 20 20 20 20   nWrite = 0;    
26da0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
26db0 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  Number of pages 
26dc0 77 72 69 74 74 65 6e 20 2a 2f 0a 0a 20 20 2f 2a  written */..  /*
26dd0 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 6d   This function m
26de0 61 79 20 6e 6f 74 20 62 65 20 63 61 6c 6c 65 64  ay not be called
26df0 20 69 66 20 70 44 62 20 68 61 73 20 61 6e 20 6f   if pDb has an o
26e00 70 65 6e 20 72 65 61 64 20 6f 72 20 77 72 69 74  pen read or writ
26e10 65 0a 20 20 2a 2a 20 74 72 61 6e 73 61 63 74 69  e.  ** transacti
26e20 6f 6e 2e 20 52 65 74 75 72 6e 20 4c 53 4d 5f 4d  on. Return LSM_M
26e30 49 53 55 53 45 20 69 66 20 61 6e 20 61 70 70 6c  ISUSE if an appl
26e40 69 63 61 74 69 6f 6e 20 61 74 74 65 6d 70 74 73  ication attempts
26e50 20 74 68 69 73 2e 20 20 2a 2f 0a 20 20 69 66 28   this.  */.  if(
26e60 20 70 44 62 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e   pDb->nTransOpen
26e70 20 7c 7c 20 70 44 62 2d 3e 70 43 73 72 20 29 20   || pDb->pCsr ) 
26e80 72 65 74 75 72 6e 20 4c 53 4d 5f 4d 49 53 55 53  return LSM_MISUS
26e90 45 5f 42 4b 50 54 3b 0a 20 20 69 66 28 20 6e 4d  E_BKPT;.  if( nM
26ea0 65 72 67 65 3c 3d 30 20 29 20 6e 4d 65 72 67 65  erge<=0 ) nMerge
26eb0 20 3d 20 70 44 62 2d 3e 6e 4d 65 72 67 65 3b 0a   = pDb->nMerge;.
26ec0 0a 20 20 6c 73 6d 46 73 50 75 72 67 65 43 61 63  .  lsmFsPurgeCac
26ed0 68 65 28 70 44 62 2d 3e 70 46 53 29 3b 0a 0a 20  he(pDb->pFS);.. 
26ee0 20 2f 2a 20 43 6f 6e 76 65 72 74 20 66 72 6f 6d   /* Convert from
26ef0 20 4b 42 20 74 6f 20 70 61 67 65 73 20 2a 2f 0a   KB to pages */.
26f00 20 20 6e 50 67 73 7a 20 3d 20 6c 73 6d 46 73 50    nPgsz = lsmFsP
26f10 61 67 65 53 69 7a 65 28 70 44 62 2d 3e 70 46 53  ageSize(pDb->pFS
26f20 29 3b 0a 20 20 69 66 28 20 6e 4b 42 3e 3d 30 20  );.  if( nKB>=0 
26f30 29 7b 0a 20 20 20 20 6e 50 61 67 65 20 3d 20 28  ){.    nPage = (
26f40 28 69 36 34 29 6e 4b 42 20 2a 20 31 30 32 34 20  (i64)nKB * 1024 
26f50 2b 20 6e 50 67 73 7a 20 2d 20 31 29 20 2f 20 6e  + nPgsz - 1) / n
26f60 50 67 73 7a 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Pgsz;.  }else{. 
26f70 20 20 20 6e 50 61 67 65 20 3d 20 2d 31 3b 0a 20     nPage = -1;. 
26f80 20 7d 0a 0a 20 20 72 63 20 3d 20 64 6f 4c 73 6d   }..  rc = doLsm
26f90 57 6f 72 6b 28 70 44 62 2c 20 6e 4d 65 72 67 65  Work(pDb, nMerge
26fa0 2c 20 6e 50 61 67 65 2c 20 26 6e 57 72 69 74 65  , nPage, &nWrite
26fb0 29 3b 0a 20 20 0a 20 20 69 66 28 20 70 6e 57 72  );.  .  if( pnWr
26fc0 69 74 65 20 29 7b 0a 20 20 20 20 2f 2a 20 43 6f  ite ){.    /* Co
26fd0 6e 76 65 72 74 20 62 61 63 6b 20 66 72 6f 6d 20  nvert back from 
26fe0 70 61 67 65 73 20 74 6f 20 4b 42 20 2a 2f 0a 20  pages to KB */. 
26ff0 20 20 20 2a 70 6e 57 72 69 74 65 20 3d 20 28 69     *pnWrite = (i
27000 6e 74 29 28 28 28 69 36 34 29 6e 57 72 69 74 65  nt)(((i64)nWrite
27010 20 2a 20 31 30 32 34 20 2b 20 6e 50 67 73 7a 20   * 1024 + nPgsz 
27020 2d 20 31 29 20 2f 20 6e 50 67 73 7a 29 3b 0a 20  - 1) / nPgsz);. 
27030 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
27040 7d 0a 0a 69 6e 74 20 6c 73 6d 5f 66 6c 75 73 68  }..int lsm_flush
27050 28 6c 73 6d 5f 64 62 20 2a 64 62 29 7b 0a 20 20  (lsm_db *db){.  
27060 69 6e 74 20 72 63 3b 0a 0a 20 20 69 66 28 20 64  int rc;..  if( d
27070 62 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 3e 30 20  b->nTransOpen>0 
27080 7c 7c 20 64 62 2d 3e 70 43 73 72 20 29 7b 0a 20  || db->pCsr ){. 
27090 20 20 20 72 63 20 3d 20 4c 53 4d 5f 4d 49 53 55     rc = LSM_MISU
270a0 53 45 5f 42 4b 50 54 3b 0a 20 20 7d 65 6c 73 65  SE_BKPT;.  }else
270b0 7b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 42 65  {.    rc = lsmBe
270c0 67 69 6e 57 72 69 74 65 54 72 61 6e 73 28 64 62  ginWriteTrans(db
270d0 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  );.    if( rc==L
270e0 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 6c  SM_OK ){.      l
270f0 73 6d 46 6c 75 73 68 54 72 65 65 54 6f 44 69 73  smFlushTreeToDis
27100 6b 28 64 62 29 3b 0a 20 20 20 20 20 20 6c 73 6d  k(db);.      lsm
27110 54 72 65 65 44 69 73 63 61 72 64 4f 6c 64 28 64  TreeDiscardOld(d
27120 62 29 3b 0a 20 20 20 20 20 20 6c 73 6d 54 72 65  b);.      lsmTre
27130 65 4d 61 6b 65 4f 6c 64 28 64 62 29 3b 0a 20 20  eMakeOld(db);.  
27140 20 20 20 20 6c 73 6d 54 72 65 65 44 69 73 63 61      lsmTreeDisca
27150 72 64 4f 6c 64 28 64 62 29 3b 0a 20 20 20 20 7d  rdOld(db);.    }
27160 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53  ..    if( rc==LS
27170 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63  M_OK ){.      rc
27180 20 3d 20 6c 73 6d 46 69 6e 69 73 68 57 72 69 74   = lsmFinishWrit
27190 65 54 72 61 6e 73 28 64 62 2c 20 31 29 3b 0a 20  eTrans(db, 1);. 
271a0 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
271b0 6c 73 6d 46 69 6e 69 73 68 57 72 69 74 65 54 72  lsmFinishWriteTr
271c0 61 6e 73 28 64 62 2c 20 30 29 3b 0a 20 20 20 20  ans(db, 0);.    
271d0 7d 0a 20 20 20 20 6c 73 6d 46 69 6e 69 73 68 52  }.    lsmFinishR
271e0 65 61 64 54 72 61 6e 73 28 64 62 29 3b 0a 20 20  eadTrans(db);.  
271f0 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
27200 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
27210 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
27220 20 69 6e 20 61 75 74 6f 2d 77 6f 72 6b 20 6d 6f   in auto-work mo
27230 64 65 20 74 6f 20 70 65 72 66 6f 72 6d 20 6d 65  de to perform me
27240 72 67 69 6e 67 20 77 6f 72 6b 20 6f 6e 0a 2a 2a  rging work on.**
27250 20 74 68 65 20 64 61 74 61 20 73 74 72 75 63 74   the data struct
27260 75 72 65 2e 20 49 74 20 70 65 72 66 6f 72 6d 73  ure. It performs
27270 20 65 6e 6f 75 67 68 20 6d 65 72 67 69 6e 67 20   enough merging 
27280 77 6f 72 6b 20 74 6f 20 70 72 65 76 65 6e 74 20  work to prevent 
27290 74 68 65 0a 2a 2a 20 68 65 69 67 68 74 20 6f 66  the.** height of
272a0 20 74 68 65 20 74 72 65 65 20 66 72 6f 6d 20 67   the tree from g
272b0 72 6f 77 69 6e 67 20 69 6e 64 65 66 69 6e 69 74  rowing indefinit
272c0 65 6c 79 20 61 73 73 75 6d 69 6e 67 20 74 68 61  ely assuming tha
272d0 74 20 72 6f 75 67 68 6c 79 0a 2a 2a 20 6e 55 6e  t roughly.** nUn
272e0 69 74 20 64 61 74 61 62 61 73 65 20 70 61 67 65  it database page
272f0 73 20 77 6f 72 74 68 20 6f 66 20 64 61 74 61 20  s worth of data 
27300 68 61 76 65 20 62 65 65 6e 20 77 72 69 74 74 65  have been writte
27310 6e 20 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  n to the databas
27320 65 0a 2a 2a 20 28 69 2e 65 2e 20 74 68 65 20 69  e.** (i.e. the i
27330 6e 2d 6d 65 6d 6f 72 79 20 74 72 65 65 29 20 73  n-memory tree) s
27340 69 6e 63 65 20 74 68 65 20 6c 61 73 74 20 63 61  ince the last ca
27350 6c 6c 2e 0a 2a 2f 0a 69 6e 74 20 6c 73 6d 53 6f  ll..*/.int lsmSo
27360 72 74 65 64 41 75 74 6f 57 6f 72 6b 28 0a 20 20  rtedAutoWork(.  
27370 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20 20  lsm_db *pDb,    
27380 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27390 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64  /* Database hand
273a0 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 55 6e 69  le */.  int nUni
273b0 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t               
273c0 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 73          /* Pages
273d0 20 6f 66 20 64 61 74 61 20 77 72 69 74 74 65 6e   of data written
273e0 20 74 6f 20 69 6e 2d 6d 65 6d 6f 72 79 20 74 72   to in-memory tr
273f0 65 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  ee */.){.  int r
27400 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20  c = LSM_OK;     
27410 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
27420 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69  turn code */.  i
27430 6e 74 20 6e 44 65 70 74 68 20 3d 20 30 3b 20 20  nt nDepth = 0;  
27440 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
27450 2a 20 43 75 72 72 65 6e 74 20 68 65 69 67 68 74  * Current height
27460 20 6f 66 20 74 72 65 65 20 28 6c 6f 6e 67 65 73   of tree (longes
27470 74 20 70 61 74 68 29 20 2a 2f 0a 20 20 4c 65 76  t path) */.  Lev
27480 65 6c 20 2a 70 4c 65 76 65 6c 3b 20 20 20 20 20  el *pLevel;     
27490 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
274a0 55 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20  Used to iterate 
274b0 74 68 72 6f 75 67 68 20 6c 65 76 65 6c 73 20 2a  through levels *
274c0 2f 0a 20 20 69 6e 74 20 62 52 65 73 74 6f 72 65  /.  int bRestore
274d0 20 3d 20 30 3b 0a 0a 20 20 61 73 73 65 72 74 28   = 0;..  assert(
274e0 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 3d 3d 30   pDb->pWorker==0
274f0 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 44   );.  assert( pD
27500 62 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 3e 30 20  b->nTransOpen>0 
27510 29 3b 0a 0a 20 20 2f 2a 20 44 65 74 65 72 6d 69  );..  /* Determi
27520 6e 65 20 68 6f 77 20 6d 61 6e 79 20 75 6e 69 74  ne how many unit
27530 73 20 6f 66 20 77 6f 72 6b 20 74 6f 20 64 6f 20  s of work to do 
27540 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  before returning
27550 2e 20 4f 6e 65 20 75 6e 69 74 20 6f 66 0a 20 20  . One unit of.  
27560 2a 2a 20 77 6f 72 6b 20 69 73 20 61 63 68 69 65  ** work is achie
27570 76 65 64 20 62 79 20 77 72 69 74 69 6e 67 20 6f  ved by writing o
27580 6e 65 20 70 61 67 65 20 28 7e 34 4b 42 29 20 6f  ne page (~4KB) o
27590 66 20 6d 65 72 67 65 64 20 64 61 74 61 2e 20 20  f merged data.  
275a0 2a 2f 0a 20 20 66 6f 72 28 70 4c 65 76 65 6c 3d  */.  for(pLevel=
275b0 6c 73 6d 44 62 53 6e 61 70 73 68 6f 74 4c 65 76  lsmDbSnapshotLev
275c0 65 6c 28 70 44 62 2d 3e 70 43 6c 69 65 6e 74 29  el(pDb->pClient)
275d0 3b 20 70 4c 65 76 65 6c 3b 20 70 4c 65 76 65 6c  ; pLevel; pLevel
275e0 3d 70 4c 65 76 65 6c 2d 3e 70 4e 65 78 74 29 7b  =pLevel->pNext){
275f0 0a 20 20 20 20 2f 2a 20 6e 44 65 70 74 68 20 2b  .    /* nDepth +
27600 3d 20 4c 53 4d 5f 4d 41 58 28 31 2c 20 70 4c 65  = LSM_MAX(1, pLe
27610 76 65 6c 2d 3e 6e 52 69 67 68 74 29 3b 20 2a 2f  vel->nRight); */
27620 0a 20 20 20 20 6e 44 65 70 74 68 20 2b 3d 20 31  .    nDepth += 1
27630 3b 0a 20 20 7d 0a 20 20 69 66 28 20 6c 73 6d 54  ;.  }.  if( lsmT
27640 72 65 65 48 61 73 4f 6c 64 28 70 44 62 29 20 29  reeHasOld(pDb) )
27650 7b 0a 20 20 20 20 6e 44 65 70 74 68 20 2b 3d 20  {.    nDepth += 
27660 31 3b 0a 20 20 20 20 62 52 65 73 74 6f 72 65 20  1;.    bRestore 
27670 3d 20 31 3b 0a 20 20 20 20 72 63 20 3d 20 6c 73  = 1;.    rc = ls
27680 6d 53 61 76 65 43 75 72 73 6f 72 73 28 70 44 62  mSaveCursors(pDb
27690 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 4c  );.    if( rc!=L
276a0 53 4d 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  SM_OK ) return r
276b0 63 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6e 44  c;.  }..  if( nD
276c0 65 70 74 68 3e 30 20 29 7b 0a 20 20 20 20 69 6e  epth>0 ){.    in
276d0 74 20 6e 52 65 6d 61 69 6e 69 6e 67 3b 20 20 20  t nRemaining;   
276e0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55              /* U
276f0 6e 69 74 73 20 6f 66 20 77 6f 72 6b 20 74 6f 20  nits of work to 
27700 64 6f 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e  do before return
27710 69 6e 67 20 2a 2f 0a 0a 20 20 20 20 6e 52 65 6d  ing */..    nRem
27720 61 69 6e 69 6e 67 20 3d 20 6e 55 6e 69 74 20 2a  aining = nUnit *
27730 20 6e 44 65 70 74 68 3b 0a 23 69 66 64 65 66 20   nDepth;.#ifdef 
27740 4c 53 4d 5f 4c 4f 47 5f 57 4f 52 4b 0a 20 20 20  LSM_LOG_WORK.   
27750 20 6c 73 6d 4c 6f 67 4d 65 73 73 61 67 65 28 70   lsmLogMessage(p
27760 44 62 2c 20 72 63 2c 20 22 6c 73 6d 53 6f 72 74  Db, rc, "lsmSort
27770 65 64 41 75 74 6f 57 6f 72 6b 28 29 3a 20 25 64  edAutoWork(): %d
27780 2a 25 64 20 3d 20 25 64 20 70 61 67 65 73 22 2c  *%d = %d pages",
27790 20 0a 20 20 20 20 20 20 20 20 6e 55 6e 69 74 2c   .        nUnit,
277a0 20 6e 44 65 70 74 68 2c 20 6e 52 65 6d 61 69 6e   nDepth, nRemain
277b0 69 6e 67 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20  ing);.#endif.   
277c0 20 61 73 73 65 72 74 28 20 6e 52 65 6d 61 69 6e   assert( nRemain
277d0 69 6e 67 3e 3d 30 20 29 3b 0a 20 20 20 20 72 63  ing>=0 );.    rc
277e0 20 3d 20 64 6f 4c 73 6d 57 6f 72 6b 28 70 44 62   = doLsmWork(pDb
277f0 2c 20 70 44 62 2d 3e 6e 4d 65 72 67 65 2c 20 6e  , pDb->nMerge, n
27800 52 65 6d 61 69 6e 69 6e 67 2c 20 30 29 3b 0a 20  Remaining, 0);. 
27810 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 42     if( rc==LSM_B
27820 55 53 59 20 29 20 72 63 20 3d 20 4c 53 4d 5f 4f  USY ) rc = LSM_O
27830 4b 3b 0a 0a 20 20 20 20 69 66 28 20 62 52 65 73  K;..    if( bRes
27840 74 6f 72 65 20 26 26 20 70 44 62 2d 3e 70 43 73  tore && pDb->pCs
27850 72 20 29 7b 0a 20 20 20 20 20 20 6c 73 6d 4d 43  r ){.      lsmMC
27860 75 72 73 6f 72 46 72 65 65 43 61 63 68 65 28 70  ursorFreeCache(p
27870 44 62 29 3b 0a 20 20 20 20 20 20 6c 73 6d 46 72  Db);.      lsmFr
27880 65 65 53 6e 61 70 73 68 6f 74 28 70 44 62 2d 3e  eeSnapshot(pDb->
27890 70 45 6e 76 2c 20 70 44 62 2d 3e 70 43 6c 69 65  pEnv, pDb->pClie
278a0 6e 74 29 3b 0a 20 20 20 20 20 20 70 44 62 2d 3e  nt);.      pDb->
278b0 70 43 6c 69 65 6e 74 20 3d 20 30 3b 0a 20 20 20  pClient = 0;.   
278c0 20 20 20 72 63 20 3d 20 6c 73 6d 43 68 65 63 6b     rc = lsmCheck
278d0 70 6f 69 6e 74 4c 6f 61 64 28 70 44 62 2c 20 30  pointLoad(pDb, 0
278e0 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
278f0 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  =LSM_OK ){.     
27900 20 20 20 72 63 20 3d 20 6c 73 6d 43 68 65 63 6b     rc = lsmCheck
27910 70 6f 69 6e 74 44 65 73 65 72 69 61 6c 69 7a 65  pointDeserialize
27920 28 70 44 62 2c 20 30 2c 20 70 44 62 2d 3e 61 53  (pDb, 0, pDb->aS
27930 6e 61 70 73 68 6f 74 2c 20 26 70 44 62 2d 3e 70  napshot, &pDb->p
27940 43 6c 69 65 6e 74 29 3b 0a 20 20 20 20 20 20 7d  Client);.      }
27950 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  .      if( rc==L
27960 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  SM_OK ){.       
27970 20 72 63 20 3d 20 6c 73 6d 52 65 73 74 6f 72 65   rc = lsmRestore
27980 43 75 72 73 6f 72 73 28 70 44 62 29 3b 0a 20 20  Cursors(pDb);.  
27990 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
279a0 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
279b0 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
279c0 74 69 6f 6e 20 69 73 20 6f 6e 6c 79 20 63 61 6c  tion is only cal
279d0 6c 65 64 20 64 75 72 69 6e 67 20 73 79 73 74 65  led during syste
279e0 6d 20 73 68 75 74 64 6f 77 6e 2e 20 54 68 65 20  m shutdown. The 
279f0 63 6f 6e 74 65 6e 74 73 20 6f 66 0a 2a 2a 20 61  contents of.** a
27a00 6e 79 20 69 6e 2d 6d 65 6d 6f 72 79 20 74 72 65  ny in-memory tre
27a10 65 73 20 70 72 65 73 65 6e 74 20 28 6f 6c 64 20  es present (old 
27a20 6f 72 20 63 75 72 72 65 6e 74 29 20 61 72 65 20  or current) are 
27a30 77 72 69 74 74 65 6e 20 6f 75 74 20 74 6f 20 64  written out to d
27a40 69 73 6b 2e 0a 2a 2f 0a 69 6e 74 20 6c 73 6d 46  isk..*/.int lsmF
27a50 6c 75 73 68 54 72 65 65 54 6f 44 69 73 6b 28 6c  lushTreeToDisk(l
27a60 73 6d 5f 64 62 20 2a 70 44 62 29 7b 0a 20 20 69  sm_db *pDb){.  i
27a70 6e 74 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 6c  nt rc;..  rc = l
27a80 73 6d 42 65 67 69 6e 57 6f 72 6b 28 70 44 62 29  smBeginWork(pDb)
27a90 3b 0a 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 4c  ;.  while( rc==L
27aa0 53 4d 5f 4f 4b 20 26 26 20 73 6f 72 74 65 64 44  SM_OK && sortedD
27ab0 62 49 73 46 75 6c 6c 28 70 44 62 29 20 29 7b 0a  bIsFull(pDb) ){.
27ac0 20 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64 57      rc = sortedW
27ad0 6f 72 6b 28 70 44 62 2c 20 32 35 36 2c 20 70 44  ork(pDb, 256, pD
27ae0 62 2d 3e 6e 4d 65 72 67 65 2c 20 31 2c 20 30 29  b->nMerge, 1, 0)
27af0 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
27b00 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  =LSM_OK ){.    r
27b10 63 20 3d 20 73 6f 72 74 65 64 4e 65 77 54 6f 70  c = sortedNewTop
27b20 6c 65 76 65 6c 28 70 44 62 2c 20 54 52 45 45 5f  level(pDb, TREE_
27b30 42 4f 54 48 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20  BOTH, 0);.  }.. 
27b40 20 6c 73 6d 46 69 6e 69 73 68 57 6f 72 6b 28 70   lsmFinishWork(p
27b50 44 62 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 72  Db, 1, &rc);.  r
27b60 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
27b70 2a 2a 20 52 65 74 75 72 6e 20 61 20 73 74 72 69  ** Return a stri
27b80 6e 67 20 72 65 70 72 65 73 65 6e 74 61 74 69 6f  ng representatio
27b90 6e 20 6f 66 20 74 68 65 20 73 65 67 6d 65 6e 74  n of the segment
27ba0 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 6f   passed as the o
27bb0 6e 6c 79 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a  nly argument..**
27bc0 20 53 70 61 63 65 20 66 6f 72 20 74 68 65 20 72   Space for the r
27bd0 65 74 75 72 6e 65 64 20 73 74 72 69 6e 67 20 69  eturned string i
27be0 73 20 61 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e  s allocated usin
27bf0 67 20 6c 73 6d 4d 61 6c 6c 6f 63 28 29 2c 20 61  g lsmMalloc(), a
27c00 6e 64 20 73 68 6f 75 6c 64 0a 2a 2a 20 62 65 20  nd should.** be 
27c10 66 72 65 65 64 20 62 79 20 74 68 65 20 63 61 6c  freed by the cal
27c20 6c 65 72 20 75 73 69 6e 67 20 6c 73 6d 46 72 65  ler using lsmFre
27c30 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63  e()..*/.static c
27c40 68 61 72 20 2a 73 65 67 54 6f 53 74 72 69 6e 67  har *segToString
27c50 28 6c 73 6d 5f 65 6e 76 20 2a 70 45 6e 76 2c 20  (lsm_env *pEnv, 
27c60 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 2c 20 69  Segment *pSeg, i
27c70 6e 74 20 6e 4d 69 6e 29 7b 0a 20 20 69 6e 74 20  nt nMin){.  int 
27c80 6e 53 69 7a 65 20 3d 20 70 53 65 67 2d 3e 6e 53  nSize = pSeg->nS
27c90 69 7a 65 3b 0a 20 20 50 67 6e 6f 20 69 52 6f 6f  ize;.  Pgno iRoo
27ca0 74 20 3d 20 70 53 65 67 2d 3e 69 52 6f 6f 74 3b  t = pSeg->iRoot;
27cb0 0a 20 20 50 67 6e 6f 20 69 46 69 72 73 74 20 3d  .  Pgno iFirst =
27cc0 20 70 53 65 67 2d 3e 69 46 69 72 73 74 3b 0a 20   pSeg->iFirst;. 
27cd0 20 50 67 6e 6f 20 69 4c 61 73 74 20 3d 20 70 53   Pgno iLast = pS
27ce0 65 67 2d 3e 69 4c 61 73 74 50 67 3b 0a 20 20 63  eg->iLastPg;.  c
27cf0 68 61 72 20 2a 7a 3b 0a 0a 20 20 63 68 61 72 20  har *z;..  char 
27d00 2a 7a 31 3b 0a 20 20 63 68 61 72 20 2a 7a 32 3b  *z1;.  char *z2;
27d10 0a 20 20 69 6e 74 20 6e 50 61 64 3b 0a 0a 20 20  .  int nPad;..  
27d20 7a 31 20 3d 20 6c 73 6d 4d 61 6c 6c 6f 63 50 72  z1 = lsmMallocPr
27d30 69 6e 74 66 28 70 45 6e 76 2c 20 22 25 64 2e 25  intf(pEnv, "%d.%
27d40 64 22 2c 20 69 46 69 72 73 74 2c 20 69 4c 61 73  d", iFirst, iLas
27d50 74 29 3b 0a 20 20 69 66 28 20 69 52 6f 6f 74 20  t);.  if( iRoot 
27d60 29 7b 0a 20 20 20 20 7a 32 20 3d 20 6c 73 6d 4d  ){.    z2 = lsmM
27d70 61 6c 6c 6f 63 50 72 69 6e 74 66 28 70 45 6e 76  allocPrintf(pEnv
27d80 2c 20 22 72 6f 6f 74 3d 25 64 22 2c 20 69 52 6f  , "root=%d", iRo
27d90 6f 74 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  ot);.  }else{.  
27da0 20 20 7a 32 20 3d 20 6c 73 6d 4d 61 6c 6c 6f 63    z2 = lsmMalloc
27db0 50 72 69 6e 74 66 28 70 45 6e 76 2c 20 22 73 69  Printf(pEnv, "si
27dc0 7a 65 3d 25 64 22 2c 20 6e 53 69 7a 65 29 3b 0a  ze=%d", nSize);.
27dd0 20 20 7d 0a 0a 20 20 6e 50 61 64 20 3d 20 6e 4d    }..  nPad = nM
27de0 69 6e 20 2d 20 32 20 2d 20 73 74 72 6c 65 6e 28  in - 2 - strlen(
27df0 7a 31 29 20 2d 20 31 20 2d 20 73 74 72 6c 65 6e  z1) - 1 - strlen
27e00 28 7a 32 29 3b 0a 20 20 6e 50 61 64 20 3d 20 4c  (z2);.  nPad = L
27e10 53 4d 5f 4d 41 58 28 30 2c 20 6e 50 61 64 29 3b  SM_MAX(0, nPad);
27e20 0a 0a 20 20 69 66 28 20 69 52 6f 6f 74 20 29 7b  ..  if( iRoot ){
27e30 0a 20 20 20 20 7a 20 3d 20 6c 73 6d 4d 61 6c 6c  .    z = lsmMall
27e40 6f 63 50 72 69 6e 74 66 28 70 45 6e 76 2c 20 22  ocPrintf(pEnv, "
27e50 2f 25 73 20 25 2a 73 25 73 5c 5c 22 2c 20 7a 31  /%s %*s%s\\", z1
27e60 2c 20 6e 50 61 64 2c 20 22 22 2c 20 7a 32 29 3b  , nPad, "", z2);
27e70 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 7a 20  .  }else{.    z 
27e80 3d 20 6c 73 6d 4d 61 6c 6c 6f 63 50 72 69 6e 74  = lsmMallocPrint
27e90 66 28 70 45 6e 76 2c 20 22 7c 25 73 20 25 2a 73  f(pEnv, "|%s %*s
27ea0 25 73 7c 22 2c 20 7a 31 2c 20 6e 50 61 64 2c 20  %s|", z1, nPad, 
27eb0 22 22 2c 20 7a 32 29 3b 0a 20 20 7d 0a 20 20 6c  "", z2);.  }.  l
27ec0 73 6d 46 72 65 65 28 70 45 6e 76 2c 20 7a 31 29  smFree(pEnv, z1)
27ed0 3b 0a 20 20 6c 73 6d 46 72 65 65 28 70 45 6e 76  ;.  lsmFree(pEnv
27ee0 2c 20 7a 32 29 3b 0a 0a 20 20 72 65 74 75 72 6e  , z2);..  return
27ef0 20 7a 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e   z;.}..static in
27f00 74 20 66 69 6c 65 54 6f 53 74 72 69 6e 67 28 0a  t fileToString(.
27f10 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20    lsm_db *pDb,  
27f20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27f30 20 20 2f 2a 20 46 6f 72 20 78 4d 61 6c 6c 6f 63    /* For xMalloc
27f40 28 29 20 2a 2f 0a 20 20 63 68 61 72 20 2a 61 42  () */.  char *aB
27f50 75 66 2c 20 0a 20 20 69 6e 74 20 6e 42 75 66 2c  uf, .  int nBuf,
27f60 20 0a 20 20 69 6e 74 20 6e 4d 69 6e 2c 0a 20 20   .  int nMin,.  
27f70 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 0a 29 7b  Segment *pSeg.){
27f80 0a 20 20 69 6e 74 20 69 20 3d 20 30 3b 0a 20 20  .  int i = 0;.  
27f90 69 66 28 20 70 53 65 67 20 29 7b 0a 20 20 20 20  if( pSeg ){.    
27fa0 63 68 61 72 20 2a 7a 53 65 67 3b 0a 0a 20 20 20  char *zSeg;..   
27fb0 20 7a 53 65 67 20 3d 20 73 65 67 54 6f 53 74 72   zSeg = segToStr
27fc0 69 6e 67 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70  ing(pDb->pEnv, p
27fd0 53 65 67 2c 20 6e 4d 69 6e 29 3b 0a 20 20 20 20  Seg, nMin);.    
27fe0 73 6e 70 72 69 6e 74 66 28 26 61 42 75 66 5b 69  snprintf(&aBuf[i
27ff0 5d 2c 20 6e 42 75 66 2d 69 2c 20 22 25 73 22 2c  ], nBuf-i, "%s",
28000 20 7a 53 65 67 29 3b 0a 20 20 20 20 69 20 2b 3d   zSeg);.    i +=
28010 20 73 74 72 6c 65 6e 28 26 61 42 75 66 5b 69 5d   strlen(&aBuf[i]
28020 29 3b 0a 20 20 20 20 6c 73 6d 46 72 65 65 28 70  );.    lsmFree(p
28030 44 62 2d 3e 70 45 6e 76 2c 20 7a 53 65 67 29 3b  Db->pEnv, zSeg);
28040 0a 0a 23 69 66 64 65 66 20 4c 53 4d 5f 4c 4f 47  ..#ifdef LSM_LOG
28050 5f 46 52 45 45 4c 49 53 54 0a 20 20 20 20 6c 73  _FREELIST.    ls
28060 6d 49 6e 66 6f 41 72 72 61 79 53 74 72 75 63 74  mInfoArrayStruct
28070 75 72 65 28 70 44 62 2c 20 31 2c 20 70 53 65 67  ure(pDb, 1, pSeg
28080 2d 3e 69 46 69 72 73 74 2c 20 26 7a 53 65 67 29  ->iFirst, &zSeg)
28090 3b 0a 20 20 20 20 73 6e 70 72 69 6e 74 66 28 26  ;.    snprintf(&
280a0 61 42 75 66 5b 69 5d 2c 20 6e 42 75 66 2d 31 2c  aBuf[i], nBuf-1,
280b0 20 22 20 20 20 20 28 25 73 29 22 2c 20 7a 53 65   "    (%s)", zSe
280c0 67 29 3b 0a 20 20 20 20 69 20 2b 3d 20 73 74 72  g);.    i += str
280d0 6c 65 6e 28 26 61 42 75 66 5b 69 5d 29 3b 0a 20  len(&aBuf[i]);. 
280e0 20 20 20 6c 73 6d 46 72 65 65 28 70 44 62 2d 3e     lsmFree(pDb->
280f0 70 45 6e 76 2c 20 7a 53 65 67 29 3b 0a 23 65 6e  pEnv, zSeg);.#en
28100 64 69 66 0a 20 20 20 20 61 42 75 66 5b 6e 42 75  dif.    aBuf[nBu
28110 66 5d 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 7b  f] = 0;.  }else{
28120 0a 20 20 20 20 61 42 75 66 5b 30 5d 20 3d 20 27  .    aBuf[0] = '
28130 5c 30 27 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  \0';.  }..  retu
28140 72 6e 20 69 3b 0a 7d 0a 0a 76 6f 69 64 20 73 6f  rn i;.}..void so
28150 72 74 65 64 44 75 6d 70 50 61 67 65 28 6c 73 6d  rtedDumpPage(lsm
28160 5f 64 62 20 2a 70 44 62 2c 20 53 65 67 6d 65 6e  _db *pDb, Segmen
28170 74 20 2a 70 52 75 6e 2c 20 50 61 67 65 20 2a 70  t *pRun, Page *p
28180 50 67 2c 20 69 6e 74 20 62 56 61 6c 73 29 7b 0a  Pg, int bVals){.
28190 20 20 42 6c 6f 62 20 62 6c 6f 62 20 3d 20 7b 30    Blob blob = {0
281a0 2c 20 30 2c 20 30 7d 3b 20 20 20 20 20 20 20 20  , 0, 0};        
281b0 20 2f 2a 20 42 6c 6f 62 20 75 73 65 64 20 66 6f   /* Blob used fo
281c0 72 20 6b 65 79 73 20 2a 2f 0a 20 20 4c 73 6d 53  r keys */.  LsmS
281d0 74 72 69 6e 67 20 73 3b 0a 20 20 69 6e 74 20 69  tring s;.  int i
281e0 3b 0a 0a 20 20 69 6e 74 20 6e 52 65 63 3b 0a 20  ;..  int nRec;. 
281f0 20 69 6e 74 20 69 50 74 72 3b 0a 20 20 69 6e 74   int iPtr;.  int
28200 20 66 6c 61 67 73 3b 0a 20 20 75 38 20 2a 61 44   flags;.  u8 *aD
28210 61 74 61 3b 0a 20 20 69 6e 74 20 6e 44 61 74 61  ata;.  int nData
28220 3b 0a 0a 20 20 61 44 61 74 61 20 3d 20 66 73 50  ;..  aData = fsP
28230 61 67 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44  ageData(pPg, &nD
28240 61 74 61 29 3b 0a 0a 20 20 6e 52 65 63 20 3d 20  ata);..  nRec = 
28250 70 61 67 65 47 65 74 4e 52 65 63 28 61 44 61 74  pageGetNRec(aDat
28260 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 69 50 74  a, nData);.  iPt
28270 72 20 3d 20 70 61 67 65 47 65 74 50 74 72 28 61  r = pageGetPtr(a
28280 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20  Data, nData);.  
28290 66 6c 61 67 73 20 3d 20 70 61 67 65 47 65 74 46  flags = pageGetF
282a0 6c 61 67 73 28 61 44 61 74 61 2c 20 6e 44 61 74  lags(aData, nDat
282b0 61 29 3b 0a 0a 20 20 6c 73 6d 53 74 72 69 6e 67  a);..  lsmString
282c0 49 6e 69 74 28 26 73 2c 20 70 44 62 2d 3e 70 45  Init(&s, pDb->pE
282d0 6e 76 29 3b 0a 20 20 6c 73 6d 53 74 72 69 6e 67  nv);.  lsmString
282e0 41 70 70 65 6e 64 66 28 26 73 2c 22 6e 43 65 6c  Appendf(&s,"nCel
282f0 6c 3d 25 64 20 69 50 74 72 3d 25 64 20 66 6c 61  l=%d iPtr=%d fla
28300 67 73 3d 25 64 20 7b 22 2c 20 6e 52 65 63 2c 20  gs=%d {", nRec, 
28310 69 50 74 72 2c 20 66 6c 61 67 73 29 3b 0a 20 20  iPtr, flags);.  
28320 69 66 28 20 66 6c 61 67 73 26 53 45 47 4d 45 4e  if( flags&SEGMEN
28330 54 5f 42 54 52 45 45 5f 46 4c 41 47 20 29 20 69  T_BTREE_FLAG ) i
28340 50 74 72 20 3d 20 30 3b 0a 0a 20 20 66 6f 72 28  Ptr = 0;..  for(
28350 69 3d 30 3b 20 69 3c 6e 52 65 63 3b 20 69 2b 2b  i=0; i<nRec; i++
28360 29 7b 0a 20 20 20 20 50 61 67 65 20 2a 70 52 65  ){.    Page *pRe
28370 66 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  f = 0;          
28380 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
28390 74 6f 20 70 61 67 65 20 69 52 65 66 20 2a 2f 0a  to page iRef */.
283a0 20 20 20 20 69 6e 74 20 69 43 68 61 72 3b 0a 20      int iChar;. 
283b0 20 20 20 75 38 20 2a 61 4b 65 79 3b 20 69 6e 74     u8 *aKey; int
283c0 20 6e 4b 65 79 20 3d 20 30 3b 20 20 20 20 20 20   nKey = 0;      
283d0 20 2f 2a 20 4b 65 79 20 2a 2f 0a 20 20 20 20 75   /* Key */.    u
283e0 38 20 2a 61 56 61 6c 3b 20 69 6e 74 20 6e 56 61  8 *aVal; int nVa
283f0 6c 20 3d 20 30 3b 20 20 20 20 20 20 20 2f 2a 20  l = 0;       /* 
28400 56 61 6c 75 65 20 2a 2f 0a 20 20 20 20 69 6e 74  Value */.    int
28410 20 69 54 6f 70 69 63 3b 0a 20 20 20 20 75 38 20   iTopic;.    u8 
28420 2a 61 43 65 6c 6c 3b 0a 20 20 20 20 69 6e 74 20  *aCell;.    int 
28430 69 50 67 50 74 72 3b 0a 20 20 20 20 69 6e 74 20  iPgPtr;.    int 
28440 65 54 79 70 65 3b 0a 0a 20 20 20 20 61 43 65 6c  eType;..    aCel
28450 6c 20 3d 20 70 61 67 65 47 65 74 43 65 6c 6c 28  l = pageGetCell(
28460 61 44 61 74 61 2c 20 6e 44 61 74 61 2c 20 69 29  aData, nData, i)
28470 3b 0a 20 20 20 20 65 54 79 70 65 20 3d 20 2a 61  ;.    eType = *a
28480 43 65 6c 6c 2b 2b 3b 0a 20 20 20 20 61 73 73 65  Cell++;.    asse
28490 72 74 28 20 28 66 6c 61 67 73 20 26 20 53 45 47  rt( (flags & SEG
284a0 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 29  MENT_BTREE_FLAG)
284b0 20 7c 7c 20 65 54 79 70 65 21 3d 30 20 29 3b 0a   || eType!=0 );.
284c0 20 20 20 20 61 43 65 6c 6c 20 2b 3d 20 6c 73 6d      aCell += lsm
284d0 56 61 72 69 6e 74 47 65 74 33 32 28 61 43 65 6c  VarintGet32(aCel
284e0 6c 2c 20 26 69 50 67 50 74 72 29 3b 0a 0a 20 20  l, &iPgPtr);..  
284f0 20 20 69 66 28 20 65 54 79 70 65 3d 3d 30 20 29    if( eType==0 )
28500 7b 0a 20 20 20 20 20 20 50 67 6e 6f 20 69 52 65  {.      Pgno iRe
28510 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f;              
28520 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62      /* Page numb
28530 65 72 20 6f 66 20 72 65 66 65 72 65 6e 63 65 64  er of referenced
28540 20 70 61 67 65 20 2a 2f 0a 20 20 20 20 20 20 61   page */.      a
28550 43 65 6c 6c 20 2b 3d 20 6c 73 6d 56 61 72 69 6e  Cell += lsmVarin
28560 74 47 65 74 36 34 28 61 43 65 6c 6c 2c 20 26 69  tGet64(aCell, &i
28570 52 65 66 29 3b 0a 20 20 20 20 20 20 6c 73 6d 46  Ref);.      lsmF
28580 73 44 62 50 61 67 65 47 65 74 28 70 44 62 2d 3e  sDbPageGet(pDb->
28590 70 46 53 2c 20 70 52 75 6e 2c 20 69 52 65 66 2c  pFS, pRun, iRef,
285a0 20 26 70 52 65 66 29 3b 0a 20 20 20 20 20 20 61   &pRef);.      a
285b0 4b 65 79 20 3d 20 70 61 67 65 47 65 74 4b 65 79  Key = pageGetKey
285c0 28 70 52 75 6e 2c 20 70 52 65 66 2c 20 30 2c 20  (pRun, pRef, 0, 
285d0 26 69 54 6f 70 69 63 2c 20 26 6e 4b 65 79 2c 20  &iTopic, &nKey, 
285e0 26 62 6c 6f 62 29 3b 0a 20 20 20 20 7d 65 6c 73  &blob);.    }els
285f0 65 7b 0a 20 20 20 20 20 20 61 43 65 6c 6c 20 2b  e{.      aCell +
28600 3d 20 6c 73 6d 56 61 72 69 6e 74 47 65 74 33 32  = lsmVarintGet32
28610 28 61 43 65 6c 6c 2c 20 26 6e 4b 65 79 29 3b 0a  (aCell, &nKey);.
28620 20 20 20 20 20 20 69 66 28 20 72 74 49 73 57 72        if( rtIsWr
28630 69 74 65 28 65 54 79 70 65 29 20 29 20 61 43 65  ite(eType) ) aCe
28640 6c 6c 20 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 47  ll += lsmVarintG
28650 65 74 33 32 28 61 43 65 6c 6c 2c 20 26 6e 56 61  et32(aCell, &nVa
28660 6c 29 3b 0a 20 20 20 20 20 20 73 6f 72 74 65 64  l);.      sorted
28670 52 65 61 64 44 61 74 61 28 30 2c 20 70 50 67 2c  ReadData(0, pPg,
28680 20 28 61 43 65 6c 6c 2d 61 44 61 74 61 29 2c 20   (aCell-aData), 
28690 6e 4b 65 79 2b 6e 56 61 6c 2c 20 28 76 6f 69 64  nKey+nVal, (void
286a0 20 2a 2a 29 26 61 4b 65 79 2c 20 26 62 6c 6f 62   **)&aKey, &blob
286b0 29 3b 0a 20 20 20 20 20 20 61 56 61 6c 20 3d 20  );.      aVal = 
286c0 26 61 4b 65 79 5b 6e 4b 65 79 5d 3b 0a 20 20 20  &aKey[nKey];.   
286d0 20 20 20 69 54 6f 70 69 63 20 3d 20 65 54 79 70     iTopic = eTyp
286e0 65 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 6c 73  e;.    }..    ls
286f0 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26  mStringAppendf(&
28700 73 2c 20 22 25 73 25 32 58 3a 22 2c 20 28 69 3d  s, "%s%2X:", (i=
28710 3d 30 3f 22 22 3a 22 20 22 29 2c 20 69 54 6f 70  =0?"":" "), iTop
28720 69 63 29 3b 0a 20 20 20 20 66 6f 72 28 69 43 68  ic);.    for(iCh
28730 61 72 3d 30 3b 20 69 43 68 61 72 3c 6e 4b 65 79  ar=0; iChar<nKey
28740 3b 20 69 43 68 61 72 2b 2b 29 7b 0a 20 20 20 20  ; iChar++){.    
28750 20 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e    lsmStringAppen
28760 64 66 28 26 73 2c 20 22 25 63 22 2c 20 69 73 61  df(&s, "%c", isa
28770 6c 6e 75 6d 28 61 4b 65 79 5b 69 43 68 61 72 5d  lnum(aKey[iChar]
28780 29 20 3f 20 61 4b 65 79 5b 69 43 68 61 72 5d 20  ) ? aKey[iChar] 
28790 3a 20 27 2e 27 29 3b 0a 20 20 20 20 7d 0a 20 20  : '.');.    }.  
287a0 20 20 69 66 28 20 6e 56 61 6c 3e 30 20 26 26 20    if( nVal>0 && 
287b0 62 56 61 6c 73 20 29 7b 0a 20 20 20 20 20 20 6c  bVals ){.      l
287c0 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28  smStringAppendf(
287d0 26 73 2c 20 22 23 23 22 29 3b 0a 20 20 20 20 20  &s, "##");.     
287e0 20 66 6f 72 28 69 43 68 61 72 3d 30 3b 20 69 43   for(iChar=0; iC
287f0 68 61 72 3c 6e 56 61 6c 3b 20 69 43 68 61 72 2b  har<nVal; iChar+
28800 2b 29 7b 0a 20 20 20 20 20 20 20 20 6c 73 6d 53  +){.        lsmS
28810 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73 2c  tringAppendf(&s,
28820 20 22 25 63 22 2c 20 69 73 61 6c 6e 75 6d 28 61   "%c", isalnum(a
28830 56 61 6c 5b 69 43 68 61 72 5d 29 20 3f 20 61 56  Val[iChar]) ? aV
28840 61 6c 5b 69 43 68 61 72 5d 20 3a 20 27 2e 27 29  al[iChar] : '.')
28850 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
28860 0a 20 20 20 20 6c 73 6d 53 74 72 69 6e 67 41 70  .    lsmStringAp
28870 70 65 6e 64 66 28 26 73 2c 20 22 20 25 64 22 2c  pendf(&s, " %d",
28880 20 69 50 67 50 74 72 2b 69 50 74 72 29 3b 0a 20   iPgPtr+iPtr);. 
28890 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65     lsmFsPageRele
288a0 61 73 65 28 70 52 65 66 29 3b 0a 20 20 7d 0a 20  ase(pRef);.  }. 
288b0 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64   lsmStringAppend
288c0 28 26 73 2c 20 22 7d 22 2c 20 31 29 3b 0a 0a 20  (&s, "}", 1);.. 
288d0 20 6c 73 6d 4c 6f 67 4d 65 73 73 61 67 65 28 70   lsmLogMessage(p
288e0 44 62 2c 20 4c 53 4d 5f 4f 4b 2c 20 22 20 20 20  Db, LSM_OK, "   
288f0 20 20 20 50 61 67 65 20 25 64 3a 20 25 73 22 2c     Page %d: %s",
28900 20 6c 73 6d 46 73 50 61 67 65 4e 75 6d 62 65 72   lsmFsPageNumber
28910 28 70 50 67 29 2c 20 73 2e 7a 29 3b 0a 20 20 6c  (pPg), s.z);.  l
28920 73 6d 53 74 72 69 6e 67 43 6c 65 61 72 28 26 73  smStringClear(&s
28930 29 3b 0a 0a 20 20 73 6f 72 74 65 64 42 6c 6f 62  );..  sortedBlob
28940 46 72 65 65 28 26 62 6c 6f 62 29 3b 0a 7d 0a 0a  Free(&blob);.}..
28950 73 74 61 74 69 63 20 76 6f 69 64 20 69 6e 66 6f  static void info
28960 43 65 6c 6c 44 75 6d 70 28 0a 20 20 6c 73 6d 5f  CellDump(.  lsm_
28970 64 62 20 2a 70 44 62 2c 20 20 20 20 20 20 20 20  db *pDb,        
28980 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
28990 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a  atabase handle *
289a0 2f 0a 20 20 53 65 67 6d 65 6e 74 20 2a 70 53 65  /.  Segment *pSe
289b0 67 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  g,              
289c0 20 20 20 20 2f 2a 20 53 65 67 6d 65 6e 74 20 70      /* Segment p
289d0 61 67 65 20 62 65 6c 6f 6e 67 73 20 74 6f 20 2a  age belongs to *
289e0 2f 0a 20 20 69 6e 74 20 62 49 6e 64 69 72 65 63  /.  int bIndirec
289f0 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
28a00 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 66      /* True to f
28a10 6f 6c 6c 6f 77 20 69 6e 64 69 72 65 63 74 20 72  ollow indirect r
28a20 65 66 73 20 2a 2f 0a 20 20 50 61 67 65 20 2a 70  efs */.  Page *p
28a30 50 67 2c 0a 20 20 69 6e 74 20 69 43 65 6c 6c 2c  Pg,.  int iCell,
28a40 0a 20 20 69 6e 74 20 2a 70 65 54 79 70 65 2c 0a  .  int *peType,.
28a50 20 20 69 6e 74 20 2a 70 69 50 67 50 74 72 2c 0a    int *piPgPtr,.
28a60 20 20 75 38 20 2a 2a 70 61 4b 65 79 2c 20 69 6e    u8 **paKey, in
28a70 74 20 2a 70 6e 4b 65 79 2c 0a 20 20 75 38 20 2a  t *pnKey,.  u8 *
28a80 2a 70 61 56 61 6c 2c 20 69 6e 74 20 2a 70 6e 56  *paVal, int *pnV
28a90 61 6c 2c 0a 20 20 42 6c 6f 62 20 2a 70 42 6c 6f  al,.  Blob *pBlo
28aa0 62 0a 29 7b 0a 20 20 75 38 20 2a 61 44 61 74 61  b.){.  u8 *aData
28ab0 3b 20 69 6e 74 20 6e 44 61 74 61 3b 20 20 20 20  ; int nData;    
28ac0 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 64         /* Page d
28ad0 61 74 61 20 2a 2f 0a 20 20 75 38 20 2a 61 4b 65  ata */.  u8 *aKe
28ae0 79 3b 20 69 6e 74 20 6e 4b 65 79 20 3d 20 30 3b  y; int nKey = 0;
28af0 20 20 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 20           /* Key 
28b00 2a 2f 0a 20 20 75 38 20 2a 61 56 61 6c 3b 20 69  */.  u8 *aVal; i
28b10 6e 74 20 6e 56 61 6c 20 3d 20 30 3b 20 20 20 20  nt nVal = 0;    
28b20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 2a 2f       /* Value */
28b30 0a 20 20 69 6e 74 20 65 54 79 70 65 3b 0a 20 20  .  int eType;.  
28b40 69 6e 74 20 69 50 67 50 74 72 3b 0a 20 20 50 61  int iPgPtr;.  Pa
28b50 67 65 20 2a 70 52 65 66 20 3d 20 30 3b 20 20 20  ge *pRef = 0;   
28b60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
28b70 20 50 6f 69 6e 74 65 72 20 74 6f 20 70 61 67 65   Pointer to page
28b80 20 69 52 65 66 20 2a 2f 0a 20 20 75 38 20 2a 61   iRef */.  u8 *a
28b90 43 65 6c 6c 3b 0a 0a 20 20 61 44 61 74 61 20 3d  Cell;..  aData =
28ba0 20 66 73 50 61 67 65 44 61 74 61 28 70 50 67 2c   fsPageData(pPg,
28bb0 20 26 6e 44 61 74 61 29 3b 0a 0a 20 20 61 43 65   &nData);..  aCe
28bc0 6c 6c 20 3d 20 70 61 67 65 47 65 74 43 65 6c 6c  ll = pageGetCell
28bd0 28 61 44 61 74 61 2c 20 6e 44 61 74 61 2c 20 69  (aData, nData, i
28be0 43 65 6c 6c 29 3b 0a 20 20 65 54 79 70 65 20 3d  Cell);.  eType =
28bf0 20 2a 61 43 65 6c 6c 2b 2b 3b 0a 20 20 61 43 65   *aCell++;.  aCe
28c00 6c 6c 20 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 47  ll += lsmVarintG
28c10 65 74 33 32 28 61 43 65 6c 6c 2c 20 26 69 50 67  et32(aCell, &iPg
28c20 50 74 72 29 3b 0a 0a 20 20 69 66 28 20 65 54 79  Ptr);..  if( eTy
28c30 70 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74  pe==0 ){.    int
28c40 20 64 75 6d 6d 79 3b 0a 20 20 20 20 50 67 6e 6f   dummy;.    Pgno
28c50 20 69 52 65 66 3b 20 20 20 20 20 20 20 20 20 20   iRef;          
28c60 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20          /* Page 
28c70 6e 75 6d 62 65 72 20 6f 66 20 72 65 66 65 72 65  number of refere
28c80 6e 63 65 64 20 70 61 67 65 20 2a 2f 0a 20 20 20  nced page */.   
28c90 20 61 43 65 6c 6c 20 2b 3d 20 6c 73 6d 56 61 72   aCell += lsmVar
28ca0 69 6e 74 47 65 74 36 34 28 61 43 65 6c 6c 2c 20  intGet64(aCell, 
28cb0 26 69 52 65 66 29 3b 0a 20 20 20 20 69 66 28 20  &iRef);.    if( 
28cc0 62 49 6e 64 69 72 65 63 74 20 29 7b 0a 20 20 20  bIndirect ){.   
28cd0 20 20 20 6c 73 6d 46 73 44 62 50 61 67 65 47 65     lsmFsDbPageGe
28ce0 74 28 70 44 62 2d 3e 70 46 53 2c 20 70 53 65 67  t(pDb->pFS, pSeg
28cf0 2c 20 69 52 65 66 2c 20 26 70 52 65 66 29 3b 0a  , iRef, &pRef);.
28d00 20 20 20 20 20 20 70 61 67 65 47 65 74 4b 65 79        pageGetKey
28d10 43 6f 70 79 28 70 44 62 2d 3e 70 45 6e 76 2c 20  Copy(pDb->pEnv, 
28d20 70 53 65 67 2c 20 70 52 65 66 2c 20 30 2c 20 26  pSeg, pRef, 0, &
28d30 64 75 6d 6d 79 2c 20 70 42 6c 6f 62 29 3b 0a 20  dummy, pBlob);. 
28d40 20 20 20 20 20 61 4b 65 79 20 3d 20 28 75 38 20       aKey = (u8 
28d50 2a 29 70 42 6c 6f 62 2d 3e 70 44 61 74 61 3b 0a  *)pBlob->pData;.
28d60 20 20 20 20 20 20 6e 4b 65 79 20 3d 20 70 42 6c        nKey = pBl
28d70 6f 62 2d 3e 6e 44 61 74 61 3b 0a 20 20 20 20 20  ob->nData;.     
28d80 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61 73   lsmFsPageReleas
28d90 65 28 70 52 65 66 29 3b 0a 20 20 20 20 7d 65 6c  e(pRef);.    }el
28da0 73 65 7b 0a 20 20 20 20 20 20 61 4b 65 79 20 3d  se{.      aKey =
28db0 20 28 75 38 20 2a 29 22 3c 69 6e 64 69 72 65 63   (u8 *)"<indirec
28dc0 74 3e 22 3b 0a 20 20 20 20 20 20 6e 4b 65 79 20  t>";.      nKey 
28dd0 3d 20 31 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 65  = 11;.    }.  }e
28de0 6c 73 65 7b 0a 20 20 20 20 61 43 65 6c 6c 20 2b  lse{.    aCell +
28df0 3d 20 6c 73 6d 56 61 72 69 6e 74 47 65 74 33 32  = lsmVarintGet32
28e00 28 61 43 65 6c 6c 2c 20 26 6e 4b 65 79 29 3b 0a  (aCell, &nKey);.
28e10 20 20 20 20 69 66 28 20 72 74 49 73 57 72 69 74      if( rtIsWrit
28e20 65 28 65 54 79 70 65 29 20 29 20 61 43 65 6c 6c  e(eType) ) aCell
28e30 20 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 47 65 74   += lsmVarintGet
28e40 33 32 28 61 43 65 6c 6c 2c 20 26 6e 56 61 6c 29  32(aCell, &nVal)
28e50 3b 0a 20 20 20 20 73 6f 72 74 65 64 52 65 61 64  ;.    sortedRead
28e60 44 61 74 61 28 70 53 65 67 2c 20 70 50 67 2c 20  Data(pSeg, pPg, 
28e70 28 61 43 65 6c 6c 2d 61 44 61 74 61 29 2c 20 6e  (aCell-aData), n
28e80 4b 65 79 2b 6e 56 61 6c 2c 20 28 76 6f 69 64 20  Key+nVal, (void 
28e90 2a 2a 29 26 61 4b 65 79 2c 20 70 42 6c 6f 62 29  **)&aKey, pBlob)
28ea0 3b 0a 20 20 20 20 61 56 61 6c 20 3d 20 26 61 4b  ;.    aVal = &aK
28eb0 65 79 5b 6e 4b 65 79 5d 3b 0a 20 20 7d 0a 0a 20  ey[nKey];.  }.. 
28ec0 20 69 66 28 20 70 65 54 79 70 65 20 29 20 2a 70   if( peType ) *p
28ed0 65 54 79 70 65 20 3d 20 65 54 79 70 65 3b 0a 20  eType = eType;. 
28ee0 20 69 66 28 20 70 69 50 67 50 74 72 20 29 20 2a   if( piPgPtr ) *
28ef0 70 69 50 67 50 74 72 20 3d 20 69 50 67 50 74 72  piPgPtr = iPgPtr
28f00 3b 0a 20 20 69 66 28 20 70 61 4b 65 79 20 29 20  ;.  if( paKey ) 
28f10 2a 70 61 4b 65 79 20 3d 20 61 4b 65 79 3b 0a 20  *paKey = aKey;. 
28f20 20 69 66 28 20 70 61 56 61 6c 20 29 20 2a 70 61   if( paVal ) *pa
28f30 56 61 6c 20 3d 20 61 56 61 6c 3b 0a 20 20 69 66  Val = aVal;.  if
28f40 28 20 70 6e 4b 65 79 20 29 20 2a 70 6e 4b 65 79  ( pnKey ) *pnKey
28f50 20 3d 20 6e 4b 65 79 3b 0a 20 20 69 66 28 20 70   = nKey;.  if( p
28f60 6e 56 61 6c 20 29 20 2a 70 6e 56 61 6c 20 3d 20  nVal ) *pnVal = 
28f70 6e 56 61 6c 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  nVal;.}..static 
28f80 69 6e 74 20 69 6e 66 6f 41 70 70 65 6e 64 42 6c  int infoAppendBl
28f90 6f 62 28 4c 73 6d 53 74 72 69 6e 67 20 2a 70 53  ob(LsmString *pS
28fa0 74 72 2c 20 69 6e 74 20 62 48 65 78 2c 20 75 38  tr, int bHex, u8
28fb0 20 2a 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 69   *z, int n){.  i
28fc0 6e 74 20 69 43 68 61 72 3b 0a 20 20 66 6f 72 28  nt iChar;.  for(
28fd0 69 43 68 61 72 3d 30 3b 20 69 43 68 61 72 3c 6e  iChar=0; iChar<n
28fe0 3b 20 69 43 68 61 72 2b 2b 29 7b 0a 20 20 20 20  ; iChar++){.    
28ff0 69 66 28 20 62 48 65 78 20 29 7b 0a 20 20 20 20  if( bHex ){.    
29000 20 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e    lsmStringAppen
29010 64 66 28 70 53 74 72 2c 20 22 25 30 32 58 22 2c  df(pStr, "%02X",
29020 20 7a 5b 69 43 68 61 72 5d 29 3b 0a 20 20 20 20   z[iChar]);.    
29030 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6c 73 6d  }else{.      lsm
29040 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28 70 53  StringAppendf(pS
29050 74 72 2c 20 22 25 63 22 2c 20 69 73 61 6c 6e 75  tr, "%c", isalnu
29060 6d 28 7a 5b 69 43 68 61 72 5d 29 20 3f 7a 5b 69  m(z[iChar]) ?z[i
29070 43 68 61 72 5d 20 3a 20 27 2e 27 29 3b 0a 20 20  Char] : '.');.  
29080 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
29090 20 4c 53 4d 5f 4f 4b 3b 0a 7d 0a 0a 23 64 65 66   LSM_OK;.}..#def
290a0 69 6e 65 20 49 4e 46 4f 5f 50 41 47 45 5f 44 55  ine INFO_PAGE_DU
290b0 4d 50 5f 44 41 54 41 20 20 20 20 20 30 78 30 31  MP_DATA     0x01
290c0 0a 23 64 65 66 69 6e 65 20 49 4e 46 4f 5f 50 41  .#define INFO_PA
290d0 47 45 5f 44 55 4d 50 5f 56 41 4c 55 45 53 20 20  GE_DUMP_VALUES  
290e0 20 30 78 30 32 0a 23 64 65 66 69 6e 65 20 49 4e   0x02.#define IN
290f0 46 4f 5f 50 41 47 45 5f 44 55 4d 50 5f 48 45 58  FO_PAGE_DUMP_HEX
29100 20 20 20 20 20 20 30 78 30 34 0a 23 64 65 66 69        0x04.#defi
29110 6e 65 20 49 4e 46 4f 5f 50 41 47 45 5f 44 55 4d  ne INFO_PAGE_DUM
29120 50 5f 49 4e 44 49 52 45 43 54 20 30 78 30 38 0a  P_INDIRECT 0x08.
29130 0a 73 74 61 74 69 63 20 69 6e 74 20 69 6e 66 6f  .static int info
29140 50 61 67 65 44 75 6d 70 28 0a 20 20 6c 73 6d 5f  PageDump(.  lsm_
29150 64 62 20 2a 70 44 62 2c 20 20 20 20 20 20 20 20  db *pDb,        
29160 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
29170 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a  atabase handle *
29180 2f 0a 20 20 50 67 6e 6f 20 69 50 67 2c 20 20 20  /.  Pgno iPg,   
29190 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
291a0 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62      /* Page numb
291b0 65 72 20 6f 66 20 70 61 67 65 20 74 6f 20 64 75  er of page to du
291c0 6d 70 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67  mp */.  int flag
291d0 73 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 4f 75  s,.  char **pzOu
291e0 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t               
291f0 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 6c 73 6d       /* OUT: lsm
29200 4d 61 6c 6c 6f 63 27 64 20 73 74 72 69 6e 67 20  Malloc'd string 
29210 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  */.){.  int rc =
29220 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20   LSM_OK;        
29230 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
29240 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 50 61 67 65  n code */.  Page
29250 20 2a 70 50 67 20 3d 20 30 3b 20 20 20 20 20 20   *pPg = 0;      
29260 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48              /* H
29270 61 6e 64 6c 65 20 66 6f 72 20 70 61 67 65 20 69  andle for page i
29280 50 67 20 2a 2f 0a 20 20 69 6e 74 20 69 2c 20 6a  Pg */.  int i, j
29290 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
292a0 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20          /* Loop 
292b0 63 6f 75 6e 74 65 72 73 20 2a 2f 0a 20 20 63 6f  counters */.  co
292c0 6e 73 74 20 69 6e 74 20 70 65 72 4c 69 6e 65 20  nst int perLine 
292d0 3d 20 31 36 3b 20 20 20 20 20 20 20 20 20 2f 2a  = 16;         /*
292e0 20 42 79 74 65 73 20 70 65 72 20 6c 69 6e 65 20   Bytes per line 
292f0 69 6e 20 74 68 65 20 72 61 77 20 68 65 78 20 64  in the raw hex d
29300 75 6d 70 20 2a 2f 0a 20 20 53 65 67 6d 65 6e 74  ump */.  Segment
29310 20 2a 70 53 65 67 20 3d 20 30 3b 0a 20 20 53 6e   *pSeg = 0;.  Sn
29320 61 70 73 68 6f 74 20 2a 70 53 6e 61 70 3b 0a 0a  apshot *pSnap;..
29330 20 20 69 6e 74 20 62 56 61 6c 75 65 73 20 3d 20    int bValues = 
29340 28 66 6c 61 67 73 20 26 20 49 4e 46 4f 5f 50 41  (flags & INFO_PA
29350 47 45 5f 44 55 4d 50 5f 56 41 4c 55 45 53 29 3b  GE_DUMP_VALUES);
29360 0a 20 20 69 6e 74 20 62 48 65 78 20 3d 20 28 66  .  int bHex = (f
29370 6c 61 67 73 20 26 20 49 4e 46 4f 5f 50 41 47 45  lags & INFO_PAGE
29380 5f 44 55 4d 50 5f 48 45 58 29 3b 0a 20 20 69 6e  _DUMP_HEX);.  in
29390 74 20 62 44 61 74 61 20 3d 20 28 66 6c 61 67 73  t bData = (flags
293a0 20 26 20 49 4e 46 4f 5f 50 41 47 45 5f 44 55 4d   & INFO_PAGE_DUM
293b0 50 5f 44 41 54 41 29 3b 0a 20 20 69 6e 74 20 62  P_DATA);.  int b
293c0 49 6e 64 69 72 65 63 74 20 3d 20 28 66 6c 61 67  Indirect = (flag
293d0 73 20 26 20 49 4e 46 4f 5f 50 41 47 45 5f 44 55  s & INFO_PAGE_DU
293e0 4d 50 5f 49 4e 44 49 52 45 43 54 29 3b 0a 0a 20  MP_INDIRECT);.. 
293f0 20 2a 70 7a 4f 75 74 20 3d 20 30 3b 0a 20 20 69   *pzOut = 0;.  i
29400 66 28 20 69 50 67 3d 3d 30 20 29 20 72 65 74 75  f( iPg==0 ) retu
29410 72 6e 20 4c 53 4d 5f 45 52 52 4f 52 3b 0a 0a 20  rn LSM_ERROR;.. 
29420 20 61 73 73 65 72 74 28 20 70 44 62 2d 3e 70 43   assert( pDb->pC
29430 6c 69 65 6e 74 20 7c 7c 20 70 44 62 2d 3e 70 57  lient || pDb->pW
29440 6f 72 6b 65 72 20 29 3b 0a 20 20 70 53 6e 61 70  orker );.  pSnap
29450 20 3d 20 70 44 62 2d 3e 70 43 6c 69 65 6e 74 3b   = pDb->pClient;
29460 0a 20 20 69 66 28 20 70 53 6e 61 70 3d 3d 30 20  .  if( pSnap==0 
29470 29 20 70 53 6e 61 70 20 3d 20 70 44 62 2d 3e 70  ) pSnap = pDb->p
29480 57 6f 72 6b 65 72 3b 0a 20 20 69 66 28 20 70 53  Worker;.  if( pS
29490 6e 61 70 2d 3e 72 65 64 69 72 65 63 74 2e 6e 3e  nap->redirect.n>
294a0 30 20 29 7b 0a 20 20 20 20 4c 65 76 65 6c 20 2a  0 ){.    Level *
294b0 70 4c 76 6c 3b 0a 20 20 20 20 69 6e 74 20 62 55  pLvl;.    int bU
294c0 73 65 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28  se = 0;.    for(
294d0 70 4c 76 6c 3d 70 53 6e 61 70 2d 3e 70 4c 65 76  pLvl=pSnap->pLev
294e0 65 6c 3b 20 70 4c 76 6c 2d 3e 70 4e 65 78 74 3b  el; pLvl->pNext;
294f0 20 70 4c 76 6c 3d 70 4c 76 6c 2d 3e 70 4e 65 78   pLvl=pLvl->pNex
29500 74 29 3b 0a 20 20 20 20 70 53 65 67 20 3d 20 28  t);.    pSeg = (
29510 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 3d 3d 30 20  pLvl->nRight==0 
29520 3f 20 26 70 4c 76 6c 2d 3e 6c 68 73 20 3a 20 26  ? &pLvl->lhs : &
29530 70 4c 76 6c 2d 3e 61 52 68 73 5b 70 4c 76 6c 2d  pLvl->aRhs[pLvl-
29540 3e 6e 52 69 67 68 74 2d 31 5d 29 3b 0a 20 20 20  >nRight-1]);.   
29550 20 72 63 20 3d 20 6c 73 6d 46 73 53 65 67 6d 65   rc = lsmFsSegme
29560 6e 74 43 6f 6e 74 61 69 6e 73 50 67 28 70 44 62  ntContainsPg(pDb
29570 2d 3e 70 46 53 2c 20 70 53 65 67 2c 20 69 50 67  ->pFS, pSeg, iPg
29580 2c 20 26 62 55 73 65 29 3b 0a 20 20 20 20 69 66  , &bUse);.    if
29590 28 20 62 55 73 65 3d 3d 30 20 29 7b 0a 20 20 20  ( bUse==0 ){.   
295a0 20 20 20 70 53 65 67 20 3d 20 30 3b 0a 20 20 20     pSeg = 0;.   
295b0 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 69 50 67   }.  }..  /* iPg
295c0 20 69 73 20 61 20 72 65 61 6c 20 70 61 67 65 20   is a real page 
295d0 6e 75 6d 62 65 72 20 28 6e 6f 74 20 73 75 62 6a  number (not subj
295e0 65 63 74 20 74 6f 20 72 65 64 69 72 65 63 74 69  ect to redirecti
295f0 6f 6e 29 2e 20 53 6f 20 69 74 20 69 73 20 73 61  on). So it is sa
29600 66 65 20 0a 20 20 2a 2a 20 74 6f 20 70 61 73 73  fe .  ** to pass
29610 20 61 20 4e 55 4c 4c 20 69 6e 20 70 6c 61 63 65   a NULL in place
29620 20 6f 66 20 74 68 65 20 73 65 67 6d 65 6e 74 20   of the segment 
29630 70 6f 69 6e 74 65 72 20 61 73 20 74 68 65 20 73  pointer as the s
29640 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 0a 20  econd argument. 
29650 20 2a 2a 20 74 6f 20 6c 73 6d 46 73 44 62 50 61   ** to lsmFsDbPa
29660 67 65 47 65 74 28 29 20 68 65 72 65 2e 20 20 2a  geGet() here.  *
29670 2f 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f  /.  if( rc==LSM_
29680 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 6c  OK ){.    rc = l
29690 73 6d 46 73 44 62 50 61 67 65 47 65 74 28 70 44  smFsDbPageGet(pD
296a0 62 2d 3e 70 46 53 2c 20 30 2c 20 69 50 67 2c 20  b->pFS, 0, iPg, 
296b0 26 70 50 67 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  &pPg);.  }..  if
296c0 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a  ( rc==LSM_OK ){.
296d0 20 20 20 20 42 6c 6f 62 20 62 6c 6f 62 20 3d 20      Blob blob = 
296e0 7b 30 2c 20 30 2c 20 30 2c 20 30 7d 3b 0a 20 20  {0, 0, 0, 0};.  
296f0 20 20 69 6e 74 20 6e 4b 65 79 57 69 64 74 68 20    int nKeyWidth 
29700 3d 20 30 3b 0a 20 20 20 20 4c 73 6d 53 74 72 69  = 0;.    LsmStri
29710 6e 67 20 73 74 72 3b 0a 20 20 20 20 69 6e 74 20  ng str;.    int 
29720 6e 52 65 63 3b 0a 20 20 20 20 69 6e 74 20 69 50  nRec;.    int iP
29730 74 72 3b 0a 20 20 20 20 69 6e 74 20 66 6c 61 67  tr;.    int flag
29740 73 3b 0a 20 20 20 20 69 6e 74 20 69 43 65 6c 6c  s;.    int iCell
29750 3b 0a 20 20 20 20 75 38 20 2a 61 44 61 74 61 3b  ;.    u8 *aData;
29760 20 69 6e 74 20 6e 44 61 74 61 3b 20 20 20 20 20   int nData;     
29770 20 20 20 20 2f 2a 20 50 61 67 65 20 64 61 74 61      /* Page data
29780 20 61 6e 64 20 73 69 7a 65 20 74 68 65 72 65 6f   and size thereo
29790 66 20 2a 2f 0a 0a 20 20 20 20 61 44 61 74 61 20  f */..    aData 
297a0 3d 20 66 73 50 61 67 65 44 61 74 61 28 70 50 67  = fsPageData(pPg
297b0 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 6e  , &nData);.    n
297c0 52 65 63 20 3d 20 70 61 67 65 47 65 74 4e 52 65  Rec = pageGetNRe
297d0 63 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b  c(aData, nData);
297e0 0a 20 20 20 20 69 50 74 72 20 3d 20 70 61 67 65  .    iPtr = page
297f0 47 65 74 50 74 72 28 61 44 61 74 61 2c 20 6e 44  GetPtr(aData, nD
29800 61 74 61 29 3b 0a 20 20 20 20 66 6c 61 67 73 20  ata);.    flags 
29810 3d 20 70 61 67 65 47 65 74 46 6c 61 67 73 28 61  = pageGetFlags(a
29820 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 0a 20  Data, nData);.. 
29830 20 20 20 6c 73 6d 53 74 72 69 6e 67 49 6e 69 74     lsmStringInit
29840 28 26 73 74 72 2c 20 70 44 62 2d 3e 70 45 6e 76  (&str, pDb->pEnv
29850 29 3b 0a 20 20 20 20 6c 73 6d 53 74 72 69 6e 67  );.    lsmString
29860 41 70 70 65 6e 64 66 28 26 73 74 72 2c 20 22 50  Appendf(&str, "P
29870 61 67 65 20 3a 20 25 6c 6c 64 20 20 28 25 64 20  age : %lld  (%d 
29880 62 79 74 65 73 29 5c 6e 22 2c 20 69 50 67 2c 20  bytes)\n", iPg, 
29890 6e 44 61 74 61 29 3b 0a 20 20 20 20 6c 73 6d 53  nData);.    lsmS
298a0 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73 74  tringAppendf(&st
298b0 72 2c 20 22 6e 52 65 63 20 3a 20 25 64 5c 6e 22  r, "nRec : %d\n"
298c0 2c 20 6e 52 65 63 29 3b 0a 20 20 20 20 6c 73 6d  , nRec);.    lsm
298d0 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73  StringAppendf(&s
298e0 74 72 2c 20 22 69 50 74 72 20 3a 20 25 64 5c 6e  tr, "iPtr : %d\n
298f0 22 2c 20 69 50 74 72 29 3b 0a 20 20 20 20 6c 73  ", iPtr);.    ls
29900 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26  mStringAppendf(&
29910 73 74 72 2c 20 22 66 6c 61 67 73 3a 20 25 30 34  str, "flags: %04
29920 78 5c 6e 22 2c 20 66 6c 61 67 73 29 3b 0a 20 20  x\n", flags);.  
29930 20 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e    lsmStringAppen
29940 64 66 28 26 73 74 72 2c 20 22 5c 6e 22 29 3b 0a  df(&str, "\n");.
29950 0a 20 20 20 20 66 6f 72 28 69 43 65 6c 6c 3d 30  .    for(iCell=0
29960 3b 20 69 43 65 6c 6c 3c 6e 52 65 63 3b 20 69 43  ; iCell<nRec; iC
29970 65 6c 6c 2b 2b 29 7b 0a 20 20 20 20 20 20 69 6e  ell++){.      in
29980 74 20 6e 4b 65 79 3b 0a 20 20 20 20 20 20 69 6e  t nKey;.      in
29990 66 6f 43 65 6c 6c 44 75 6d 70 28 0a 20 20 20 20  foCellDump(.    
299a0 20 20 20 20 20 20 70 44 62 2c 20 70 53 65 67 2c        pDb, pSeg,
299b0 20 62 49 6e 64 69 72 65 63 74 2c 20 70 50 67 2c   bIndirect, pPg,
299c0 20 69 43 65 6c 6c 2c 20 30 2c 20 30 2c 20 30 2c   iCell, 0, 0, 0,
299d0 20 26 6e 4b 65 79 2c 20 30 2c 20 30 2c 20 26 62   &nKey, 0, 0, &b
299e0 6c 6f 62 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  lob.      );.   
299f0 20 20 20 69 66 28 20 6e 4b 65 79 3e 6e 4b 65 79     if( nKey>nKey
29a00 57 69 64 74 68 20 29 20 6e 4b 65 79 57 69 64 74  Width ) nKeyWidt
29a10 68 20 3d 20 6e 4b 65 79 3b 0a 20 20 20 20 7d 0a  h = nKey;.    }.
29a20 20 20 20 20 69 66 28 20 62 48 65 78 20 29 20 6e      if( bHex ) n
29a30 4b 65 79 57 69 64 74 68 20 3d 20 6e 4b 65 79 57  KeyWidth = nKeyW
29a40 69 64 74 68 20 2a 20 32 3b 0a 0a 20 20 20 20 66  idth * 2;..    f
29a50 6f 72 28 69 43 65 6c 6c 3d 30 3b 20 69 43 65 6c  or(iCell=0; iCel
29a60 6c 3c 6e 52 65 63 3b 20 69 43 65 6c 6c 2b 2b 29  l<nRec; iCell++)
29a70 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 4b 65 79  {.      u8 *aKey
29a80 3b 20 69 6e 74 20 6e 4b 65 79 20 3d 20 30 3b 20  ; int nKey = 0; 
29a90 20 20 20 20 20 20 2f 2a 20 4b 65 79 20 2a 2f 0a        /* Key */.
29aa0 20 20 20 20 20 20 75 38 20 2a 61 56 61 6c 3b 20        u8 *aVal; 
29ab0 69 6e 74 20 6e 56 61 6c 20 3d 20 30 3b 20 20 20  int nVal = 0;   
29ac0 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 2a 2f 0a      /* Value */.
29ad0 20 20 20 20 20 20 69 6e 74 20 69 50 67 50 74 72        int iPgPtr
29ae0 3b 0a 20 20 20 20 20 20 69 6e 74 20 65 54 79 70  ;.      int eTyp
29af0 65 3b 0a 20 20 20 20 20 20 50 67 6e 6f 20 69 41  e;.      Pgno iA
29b00 62 73 50 74 72 3b 0a 20 20 20 20 20 20 63 68 61  bsPtr;.      cha
29b10 72 20 7a 46 6c 61 67 73 5b 38 5d 3b 0a 0a 20 20  r zFlags[8];..  
29b20 20 20 20 20 69 6e 66 6f 43 65 6c 6c 44 75 6d 70      infoCellDump
29b30 28 70 44 62 2c 20 70 53 65 67 2c 20 62 49 6e 64  (pDb, pSeg, bInd
29b40 69 72 65 63 74 2c 20 70 50 67 2c 20 69 43 65 6c  irect, pPg, iCel
29b50 6c 2c 20 26 65 54 79 70 65 2c 20 26 69 50 67 50  l, &eType, &iPgP
29b60 74 72 2c 0a 20 20 20 20 20 20 20 20 20 20 26 61  tr,.          &a
29b70 4b 65 79 2c 20 26 6e 4b 65 79 2c 20 26 61 56 61  Key, &nKey, &aVa
29b80 6c 2c 20 26 6e 56 61 6c 2c 20 26 62 6c 6f 62 0a  l, &nVal, &blob.
29b90 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 69        );.      i
29ba0 41 62 73 50 74 72 20 3d 20 69 50 67 50 74 72 20  AbsPtr = iPgPtr 
29bb0 2b 20 28 28 66 6c 61 67 73 20 26 20 53 45 47 4d  + ((flags & SEGM
29bc0 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 29 20  ENT_BTREE_FLAG) 
29bd0 3f 20 30 20 3a 20 69 50 74 72 29 3b 0a 0a 20 20  ? 0 : iPtr);..  
29be0 20 20 20 20 6c 73 6d 46 6c 61 67 73 54 6f 53 74      lsmFlagsToSt
29bf0 72 69 6e 67 28 65 54 79 70 65 2c 20 7a 46 6c 61  ring(eType, zFla
29c00 67 73 29 3b 0a 20 20 20 20 20 20 6c 73 6d 53 74  gs);.      lsmSt
29c10 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73 74 72  ringAppendf(&str
29c20 2c 20 22 25 73 20 25 64 20 28 25 73 29 20 22 2c  , "%s %d (%s) ",
29c30 20 0a 20 20 20 20 20 20 20 20 20 20 7a 46 6c 61   .          zFla
29c40 67 73 2c 20 69 41 62 73 50 74 72 2c 20 28 72 74  gs, iAbsPtr, (rt
29c50 54 6f 70 69 63 28 65 54 79 70 65 29 20 3f 20 22  Topic(eType) ? "
29c60 73 79 73 22 20 3a 20 22 75 73 72 22 29 0a 20 20  sys" : "usr").  
29c70 20 20 20 20 29 3b 0a 20 20 20 20 20 20 69 6e 66      );.      inf
29c80 6f 41 70 70 65 6e 64 42 6c 6f 62 28 26 73 74 72  oAppendBlob(&str
29c90 2c 20 62 48 65 78 2c 20 61 4b 65 79 2c 20 6e 4b  , bHex, aKey, nK
29ca0 65 79 29 3b 20 0a 20 20 20 20 20 20 69 66 28 20  ey); .      if( 
29cb0 6e 56 61 6c 3e 30 20 26 26 20 62 56 61 6c 75 65  nVal>0 && bValue
29cc0 73 20 29 7b 0a 20 20 20 20 20 20 20 20 6c 73 6d  s ){.        lsm
29cd0 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73  StringAppendf(&s
29ce0 74 72 2c 20 22 25 2a 73 22 2c 20 6e 4b 65 79 57  tr, "%*s", nKeyW
29cf0 69 64 74 68 20 2d 20 28 6e 4b 65 79 2a 28 31 2b  idth - (nKey*(1+
29d00 62 48 65 78 29 29 2c 20 22 22 29 3b 0a 20 20 20  bHex)), "");.   
29d10 20 20 20 20 20 6c 73 6d 53 74 72 69 6e 67 41 70       lsmStringAp
29d20 70 65 6e 64 66 28 26 73 74 72 2c 20 22 20 22 29  pendf(&str, " ")
29d30 3b 0a 20 20 20 20 20 20 20 20 69 6e 66 6f 41 70  ;.        infoAp
29d40 70 65 6e 64 42 6c 6f 62 28 26 73 74 72 2c 20 62  pendBlob(&str, b
29d50 48 65 78 2c 20 61 56 61 6c 2c 20 6e 56 61 6c 29  Hex, aVal, nVal)
29d60 3b 20 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  ; .      }.     
29d70 20 69 66 28 20 72 74 54 6f 70 69 63 28 65 54 79   if( rtTopic(eTy
29d80 70 65 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69  pe) ){.        i
29d90 6e 74 20 69 42 6c 6b 20 3d 20 28 69 6e 74 29 7e  nt iBlk = (int)~
29da0 6c 73 6d 47 65 74 55 33 32 28 61 4b 65 79 29 3b  lsmGetU32(aKey);
29db0 0a 20 20 20 20 20 20 20 20 6c 73 6d 53 74 72 69  .        lsmStri
29dc0 6e 67 41 70 70 65 6e 64 66 28 26 73 74 72 2c 20  ngAppendf(&str, 
29dd0 22 20 20 28 62 6c 6f 63 6b 3d 25 64 22 2c 20 69  "  (block=%d", i
29de0 42 6c 6b 29 3b 0a 20 20 20 20 20 20 20 20 69 66  Blk);.        if
29df0 28 20 6e 56 61 6c 3e 30 20 29 7b 0a 20 20 20 20  ( nVal>0 ){.    
29e00 20 20 20 20 20 20 69 36 34 20 69 53 6e 61 70 20        i64 iSnap 
29e10 3d 20 6c 73 6d 47 65 74 55 36 34 28 61 56 61 6c  = lsmGetU64(aVal
29e20 29 3b 0a 20 20 20 20 20 20 20 20 20 20 6c 73 6d  );.          lsm
29e30 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73  StringAppendf(&s
29e40 74 72 2c 20 22 20 73 6e 61 70 73 68 6f 74 3d 25  tr, " snapshot=%
29e50 6c 6c 64 22 2c 20 69 53 6e 61 70 29 3b 0a 20 20  lld", iSnap);.  
29e60 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
29e70 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66  lsmStringAppendf
29e80 28 26 73 74 72 2c 20 22 29 22 29 3b 0a 20 20 20  (&str, ")");.   
29e90 20 20 20 7d 0a 20 20 20 20 20 20 6c 73 6d 53 74     }.      lsmSt
29ea0 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73 74 72  ringAppendf(&str
29eb0 2c 20 22 5c 6e 22 29 3b 0a 20 20 20 20 7d 0a 0a  , "\n");.    }..
29ec0 20 20 20 20 69 66 28 20 62 44 61 74 61 20 29 7b      if( bData ){
29ed0 0a 20 20 20 20 20 20 6c 73 6d 53 74 72 69 6e 67  .      lsmString
29ee0 41 70 70 65 6e 64 66 28 26 73 74 72 2c 20 22 5c  Appendf(&str, "\
29ef0 6e 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  n---------------
29f00 2d 2d 2d 2d 22 20 0a 20 20 20 20 20 20 20 20 20  ----" .         
29f10 20 22 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d   "--------------
29f20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
29f30 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
29f40 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 5c  ---------------\
29f50 6e 22 29 3b 0a 20 20 20 20 20 20 6c 73 6d 53 74  n");.      lsmSt
29f60 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73 74 72  ringAppendf(&str
29f70 2c 20 22 50 61 67 65 20 25 64 5c 6e 22 2c 0a 20  , "Page %d\n",. 
29f80 20 20 20 20 20 20 20 20 20 69 50 67 2c 20 28 69           iPg, (i
29f90 50 67 2d 31 29 2a 6e 44 61 74 61 2c 20 69 50 67  Pg-1)*nData, iPg
29fa0 2a 6e 44 61 74 61 20 2d 20 31 29 3b 0a 20 20 20  *nData - 1);.   
29fb0 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 44     for(i=0; i<nD
29fc0 61 74 61 3b 20 69 20 2b 3d 20 70 65 72 4c 69 6e  ata; i += perLin
29fd0 65 29 7b 0a 20 20 20 20 20 20 20 20 6c 73 6d 53  e){.        lsmS
29fe0 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73 74  tringAppendf(&st
29ff0 72 2c 20 22 25 30 34 78 3a 20 22 2c 20 69 29 3b  r, "%04x: ", i);
2a000 0a 20 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 30  .        for(j=0
2a010 3b 20 6a 3c 70 65 72 4c 69 6e 65 3b 20 6a 2b 2b  ; j<perLine; j++
2a020 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  ){.          if(
2a030 20 69 2b 6a 3e 6e 44 61 74 61 20 29 7b 0a 20 20   i+j>nData ){.  
2a040 20 20 20 20 20 20 20 20 20 20 6c 73 6d 53 74 72            lsmStr
2a050 69 6e 67 41 70 70 65 6e 64 66 28 26 73 74 72 2c  ingAppendf(&str,
2a060 20 22 20 20 20 22 29 3b 0a 20 20 20 20 20 20 20   "   ");.       
2a070 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
2a080 20 20 20 20 20 20 6c 73 6d 53 74 72 69 6e 67 41        lsmStringA
2a090 70 70 65 6e 64 66 28 26 73 74 72 2c 20 22 25 30  ppendf(&str, "%0
2a0a0 32 78 20 22 2c 20 61 44 61 74 61 5b 69 2b 6a 5d  2x ", aData[i+j]
2a0b0 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  );.          }. 
2a0c0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
2a0d0 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64   lsmStringAppend
2a0e0 66 28 26 73 74 72 2c 20 22 20 20 22 29 3b 0a 20  f(&str, "  ");. 
2a0f0 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20         for(j=0; 
2a100 6a 3c 70 65 72 4c 69 6e 65 3b 20 6a 2b 2b 29 7b  j<perLine; j++){
2a110 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 69  .          if( i
2a120 2b 6a 3e 6e 44 61 74 61 20 29 7b 0a 20 20 20 20  +j>nData ){.    
2a130 20 20 20 20 20 20 20 20 6c 73 6d 53 74 72 69 6e          lsmStrin
2a140 67 41 70 70 65 6e 64 66 28 26 73 74 72 2c 20 22  gAppendf(&str, "
2a150 20 22 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d   ");.          }
2a160 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20  else{.          
2a170 20 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e    lsmStringAppen
2a180 64 66 28 26 73 74 72 2c 22 25 63 22 2c 20 69 73  df(&str,"%c", is
2a190 70 72 69 6e 74 28 61 44 61 74 61 5b 69 2b 6a 5d  print(aData[i+j]
2a1a0 29 20 3f 20 61 44 61 74 61 5b 69 2b 6a 5d 20 3a  ) ? aData[i+j] :
2a1b0 20 27 2e 27 29 3b 0a 20 20 20 20 20 20 20 20 20   '.');.         
2a1c0 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   }.        }.   
2a1d0 20 20 20 20 20 6c 73 6d 53 74 72 69 6e 67 41 70       lsmStringAp
2a1e0 70 65 6e 64 66 28 26 73 74 72 2c 22 5c 6e 22 29  pendf(&str,"\n")
2a1f0 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
2a200 0a 20 20 20 20 2a 70 7a 4f 75 74 20 3d 20 73 74  .    *pzOut = st
2a210 72 2e 7a 3b 0a 20 20 20 20 73 6f 72 74 65 64 42  r.z;.    sortedB
2a220 6c 6f 62 46 72 65 65 28 26 62 6c 6f 62 29 3b 0a  lobFree(&blob);.
2a230 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c      lsmFsPageRel
2a240 65 61 73 65 28 70 50 67 29 3b 0a 20 20 7d 0a 0a  ease(pPg);.  }..
2a250 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
2a260 69 6e 74 20 6c 73 6d 49 6e 66 6f 50 61 67 65 44  int lsmInfoPageD
2a270 75 6d 70 28 0a 20 20 6c 73 6d 5f 64 62 20 2a 70  ump(.  lsm_db *p
2a280 44 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  Db,             
2a290 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
2a2a0 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 50  se handle */.  P
2a2b0 67 6e 6f 20 69 50 67 2c 20 20 20 20 20 20 20 20  gno iPg,        
2a2c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2a2d0 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20 6f 66  * Page number of
2a2e0 20 70 61 67 65 20 74 6f 20 64 75 6d 70 20 2a 2f   page to dump */
2a2f0 0a 20 20 69 6e 74 20 62 48 65 78 2c 20 20 20 20  .  int bHex,    
2a300 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a310 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 6f 75     /* True to ou
2a320 74 70 75 74 20 6b 65 79 2f 76 61 6c 75 65 20 69  tput key/value i
2a330 6e 20 68 65 78 20 66 6f 72 6d 20 2a 2f 0a 20 20  n hex form */.  
2a340 63 68 61 72 20 2a 2a 70 7a 4f 75 74 20 20 20 20  char **pzOut    
2a350 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a360 2f 2a 20 4f 55 54 3a 20 6c 73 6d 4d 61 6c 6c 6f  /* OUT: lsmMallo
2a370 63 27 64 20 73 74 72 69 6e 67 20 2a 2f 0a 29 7b  c'd string */.){
2a380 0a 20 20 69 6e 74 20 66 6c 61 67 73 20 3d 20 49  .  int flags = I
2a390 4e 46 4f 5f 50 41 47 45 5f 44 55 4d 50 5f 44 41  NFO_PAGE_DUMP_DA
2a3a0 54 41 20 7c 20 49 4e 46 4f 5f 50 41 47 45 5f 44  TA | INFO_PAGE_D
2a3b0 55 4d 50 5f 56 41 4c 55 45 53 3b 0a 20 20 69 66  UMP_VALUES;.  if
2a3c0 28 20 62 48 65 78 20 29 20 66 6c 61 67 73 20 7c  ( bHex ) flags |
2a3d0 3d 20 49 4e 46 4f 5f 50 41 47 45 5f 44 55 4d 50  = INFO_PAGE_DUMP
2a3e0 5f 48 45 58 3b 0a 20 20 72 65 74 75 72 6e 20 69  _HEX;.  return i
2a3f0 6e 66 6f 50 61 67 65 44 75 6d 70 28 70 44 62 2c  nfoPageDump(pDb,
2a400 20 69 50 67 2c 20 66 6c 61 67 73 2c 20 70 7a 4f   iPg, flags, pzO
2a410 75 74 29 3b 0a 7d 0a 0a 76 6f 69 64 20 73 6f 72  ut);.}..void sor
2a420 74 65 64 44 75 6d 70 53 65 67 6d 65 6e 74 28 6c  tedDumpSegment(l
2a430 73 6d 5f 64 62 20 2a 70 44 62 2c 20 53 65 67 6d  sm_db *pDb, Segm
2a440 65 6e 74 20 2a 70 52 75 6e 2c 20 69 6e 74 20 62  ent *pRun, int b
2a450 56 61 6c 73 29 7b 0a 20 20 61 73 73 65 72 74 28  Vals){.  assert(
2a460 20 70 44 62 2d 3e 78 4c 6f 67 20 29 3b 0a 20 20   pDb->xLog );.  
2a470 69 66 28 20 70 52 75 6e 20 26 26 20 70 52 75 6e  if( pRun && pRun
2a480 2d 3e 69 46 69 72 73 74 20 29 7b 0a 20 20 20 20  ->iFirst ){.    
2a490 69 6e 74 20 66 6c 61 67 73 20 3d 20 28 62 56 61  int flags = (bVa
2a4a0 6c 73 20 3f 20 49 4e 46 4f 5f 50 41 47 45 5f 44  ls ? INFO_PAGE_D
2a4b0 55 4d 50 5f 56 41 4c 55 45 53 20 3a 20 30 29 3b  UMP_VALUES : 0);
2a4c0 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 65 67 3b  .    char *zSeg;
2a4d0 0a 20 20 20 20 50 61 67 65 20 2a 70 50 67 3b 0a  .    Page *pPg;.
2a4e0 0a 20 20 20 20 7a 53 65 67 20 3d 20 73 65 67 54  .    zSeg = segT
2a4f0 6f 53 74 72 69 6e 67 28 70 44 62 2d 3e 70 45 6e  oString(pDb->pEn
2a500 76 2c 20 70 52 75 6e 2c 20 30 29 3b 0a 20 20 20  v, pRun, 0);.   
2a510 20 6c 73 6d 4c 6f 67 4d 65 73 73 61 67 65 28 70   lsmLogMessage(p
2a520 44 62 2c 20 4c 53 4d 5f 4f 4b 2c 20 22 53 65 67  Db, LSM_OK, "Seg
2a530 6d 65 6e 74 3a 20 25 73 22 2c 20 7a 53 65 67 29  ment: %s", zSeg)
2a540 3b 0a 20 20 20 20 6c 73 6d 46 72 65 65 28 70 44  ;.    lsmFree(pD
2a550 62 2d 3e 70 45 6e 76 2c 20 7a 53 65 67 29 3b 0a  b->pEnv, zSeg);.
2a560 0a 20 20 20 20 6c 73 6d 46 73 44 62 50 61 67 65  .    lsmFsDbPage
2a570 47 65 74 28 70 44 62 2d 3e 70 46 53 2c 20 70 52  Get(pDb->pFS, pR
2a580 75 6e 2c 20 70 52 75 6e 2d 3e 69 46 69 72 73 74  un, pRun->iFirst
2a590 2c 20 26 70 50 67 29 3b 0a 20 20 20 20 77 68 69  , &pPg);.    whi
2a5a0 6c 65 28 20 70 50 67 20 29 7b 0a 20 20 20 20 20  le( pPg ){.     
2a5b0 20 50 61 67 65 20 2a 70 4e 65 78 74 3b 0a 20 20   Page *pNext;.  
2a5c0 20 20 20 20 63 68 61 72 20 2a 7a 20 3d 20 30 3b      char *z = 0;
2a5d0 0a 20 20 20 20 20 20 69 6e 66 6f 50 61 67 65 44  .      infoPageD
2a5e0 75 6d 70 28 70 44 62 2c 20 6c 73 6d 46 73 50 61  ump(pDb, lsmFsPa
2a5f0 67 65 4e 75 6d 62 65 72 28 70 50 67 29 2c 20 66  geNumber(pPg), f
2a600 6c 61 67 73 2c 20 26 7a 29 3b 0a 20 20 20 20 20  lags, &z);.     
2a610 20 6c 73 6d 4c 6f 67 4d 65 73 73 61 67 65 28 70   lsmLogMessage(p
2a620 44 62 2c 20 4c 53 4d 5f 4f 4b 2c 20 22 25 73 22  Db, LSM_OK, "%s"
2a630 2c 20 7a 29 3b 0a 20 20 20 20 20 20 6c 73 6d 46  , z);.      lsmF
2a640 72 65 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 7a  ree(pDb->pEnv, z
2a650 29 3b 0a 23 69 66 20 30 0a 20 20 20 20 20 20 73  );.#if 0.      s
2a660 6f 72 74 65 64 44 75 6d 70 50 61 67 65 28 70 44  ortedDumpPage(pD
2a670 62 2c 20 70 52 75 6e 2c 20 70 50 67 2c 20 62 56  b, pRun, pPg, bV
2a680 61 6c 73 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20  als);.#endif.   
2a690 20 20 20 6c 73 6d 46 73 44 62 50 61 67 65 4e 65     lsmFsDbPageNe
2a6a0 78 74 28 70 52 75 6e 2c 20 70 50 67 2c 20 31 2c  xt(pRun, pPg, 1,
2a6b0 20 26 70 4e 65 78 74 29 3b 0a 20 20 20 20 20 20   &pNext);.      
2a6c0 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61 73 65  lsmFsPageRelease
2a6d0 28 70 50 67 29 3b 0a 20 20 20 20 20 20 70 50 67  (pPg);.      pPg
2a6e0 20 3d 20 70 4e 65 78 74 3b 0a 20 20 20 20 7d 0a   = pNext;.    }.
2a6f0 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 76    }.}../*.** Inv
2a700 6f 6b 65 20 74 68 65 20 6c 6f 67 20 63 61 6c 6c  oke the log call
2a710 62 61 63 6b 20 7a 65 72 6f 20 6f 72 20 6d 6f 72  back zero or mor
2a720 65 20 74 69 6d 65 73 20 77 69 74 68 20 6d 65 73  e times with mes
2a730 73 61 67 65 73 20 74 68 61 74 20 64 65 73 63 72  sages that descr
2a740 69 62 65 0a 2a 2a 20 74 68 65 20 63 75 72 72 65  ibe.** the curre
2a750 6e 74 20 64 61 74 61 62 61 73 65 20 73 74 72 75  nt database stru
2a760 63 74 75 72 65 2e 0a 2a 2f 0a 76 6f 69 64 20 6c  cture..*/.void l
2a770 73 6d 53 6f 72 74 65 64 44 75 6d 70 53 74 72 75  smSortedDumpStru
2a780 63 74 75 72 65 28 0a 20 20 6c 73 6d 5f 64 62 20  cture(.  lsm_db 
2a790 2a 70 44 62 2c 20 20 20 20 20 20 20 20 20 20 20  *pDb,           
2a7a0 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
2a7b0 62 61 73 65 20 68 61 6e 64 6c 65 20 28 75 73 65  base handle (use
2a7c0 64 20 66 6f 72 20 78 4c 6f 67 20 63 61 6c 6c 62  d for xLog callb
2a7d0 61 63 6b 29 20 2a 2f 0a 20 20 53 6e 61 70 73 68  ack) */.  Snapsh
2a7e0 6f 74 20 2a 70 53 6e 61 70 2c 20 20 20 20 20 20  ot *pSnap,      
2a7f0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6e 61            /* Sna
2a800 70 73 68 6f 74 20 74 6f 20 64 75 6d 70 20 2a 2f  pshot to dump */
2a810 0a 20 20 69 6e 74 20 62 4b 65 79 73 2c 20 20 20  .  int bKeys,   
2a820 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a830 20 20 20 2f 2a 20 4f 75 74 70 75 74 20 74 68 65     /* Output the
2a840 20 6b 65 79 73 20 66 72 6f 6d 20 65 61 63 68 20   keys from each 
2a850 73 65 67 6d 65 6e 74 20 2a 2f 0a 20 20 69 6e 74  segment */.  int
2a860 20 62 56 61 6c 73 2c 20 20 20 20 20 20 20 20 20   bVals,         
2a870 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2a880 4f 75 74 70 75 74 20 74 68 65 20 76 61 6c 75 65  Output the value
2a890 73 20 66 72 6f 6d 20 65 61 63 68 20 73 65 67 6d  s from each segm
2a8a0 65 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ent */.  const c
2a8b0 68 61 72 20 2a 7a 57 68 79 20 20 20 20 20 20 20  har *zWhy       
2a8c0 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 70 74           /* Capt
2a8d0 69 6f 6e 20 74 6f 20 70 72 69 6e 74 20 6e 65 61  ion to print nea
2a8e0 72 20 74 6f 70 20 6f 66 20 64 75 6d 70 20 2a 2f  r top of dump */
2a8f0 0a 29 7b 0a 20 20 53 6e 61 70 73 68 6f 74 20 2a  .){.  Snapshot *
2a900 70 44 75 6d 70 20 3d 20 70 53 6e 61 70 3b 0a 20  pDump = pSnap;. 
2a910 20 4c 65 76 65 6c 20 2a 70 54 6f 70 4c 65 76 65   Level *pTopLeve
2a920 6c 3b 0a 20 20 63 68 61 72 20 2a 7a 46 72 65 65  l;.  char *zFree
2a930 20 3d 20 30 3b 0a 0a 20 20 61 73 73 65 72 74 28   = 0;..  assert(
2a940 20 70 53 6e 61 70 20 29 3b 0a 20 20 70 54 6f 70   pSnap );.  pTop
2a950 4c 65 76 65 6c 20 3d 20 6c 73 6d 44 62 53 6e 61  Level = lsmDbSna
2a960 70 73 68 6f 74 4c 65 76 65 6c 28 70 44 75 6d 70  pshotLevel(pDump
2a970 29 3b 0a 20 20 69 66 28 20 70 44 62 2d 3e 78 4c  );.  if( pDb->xL
2a980 6f 67 20 26 26 20 70 54 6f 70 4c 65 76 65 6c 20  og && pTopLevel 
2a990 29 7b 0a 20 20 20 20 73 74 61 74 69 63 20 69 6e  ){.    static in
2a9a0 74 20 6e 43 61 6c 6c 20 3d 20 30 3b 0a 20 20 20  t nCall = 0;.   
2a9b0 20 4c 65 76 65 6c 20 2a 70 4c 65 76 65 6c 3b 0a   Level *pLevel;.
2a9c0 20 20 20 20 69 6e 74 20 69 4c 65 76 65 6c 20 3d      int iLevel =
2a9d0 20 30 3b 0a 0a 20 20 20 20 6e 43 61 6c 6c 2b 2b   0;..    nCall++
2a9e0 3b 0a 20 20 20 20 6c 73 6d 4c 6f 67 4d 65 73 73  ;.    lsmLogMess
2a9f0 61 67 65 28 70 44 62 2c 20 4c 53 4d 5f 4f 4b 2c  age(pDb, LSM_OK,
2aa00 20 22 44 61 74 61 62 61 73 65 20 73 74 72 75 63   "Database struc
2aa10 74 75 72 65 20 25 64 20 28 25 73 29 22 2c 20 6e  ture %d (%s)", n
2aa20 43 61 6c 6c 2c 20 7a 57 68 79 29 3b 0a 0a 23 69  Call, zWhy);..#i
2aa30 66 20 30 0a 20 20 20 20 69 66 28 20 6e 43 61 6c  f 0.    if( nCal
2aa40 6c 3d 3d 31 30 33 31 20 7c 7c 20 6e 43 61 6c 6c  l==1031 || nCall
2aa50 3d 3d 31 30 33 32 20 29 20 62 4b 65 79 73 3d 31  ==1032 ) bKeys=1
2aa60 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 20 20 66 6f  ;.#endif..    fo
2aa70 72 28 70 4c 65 76 65 6c 3d 70 54 6f 70 4c 65 76  r(pLevel=pTopLev
2aa80 65 6c 3b 20 70 4c 65 76 65 6c 3b 20 70 4c 65 76  el; pLevel; pLev
2aa90 65 6c 3d 70 4c 65 76 65 6c 2d 3e 70 4e 65 78 74  el=pLevel->pNext
2aaa0 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 7a 4c  ){.      char zL
2aab0 65 66 74 5b 31 30 32 34 5d 3b 0a 20 20 20 20 20  eft[1024];.     
2aac0 20 63 68 61 72 20 7a 52 69 67 68 74 5b 31 30 32   char zRight[102
2aad0 34 5d 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 20  4];.      int i 
2aae0 3d 20 30 3b 0a 0a 20 20 20 20 20 20 53 65 67 6d  = 0;..      Segm
2aaf0 65 6e 74 20 2a 61 4c 65 66 74 5b 32 34 5d 3b 20  ent *aLeft[24]; 
2ab00 20 0a 20 20 20 20 20 20 53 65 67 6d 65 6e 74 20   .      Segment 
2ab10 2a 61 52 69 67 68 74 5b 32 34 5d 3b 0a 0a 20 20  *aRight[24];..  
2ab20 20 20 20 20 69 6e 74 20 6e 4c 65 66 74 20 3d 20      int nLeft = 
2ab30 30 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 52 69  0;.      int nRi
2ab40 67 68 74 20 3d 20 30 3b 0a 0a 20 20 20 20 20 20  ght = 0;..      
2ab50 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 20 3d 20  Segment *pSeg = 
2ab60 26 70 4c 65 76 65 6c 2d 3e 6c 68 73 3b 0a 20 20  &pLevel->lhs;.  
2ab70 20 20 20 20 61 4c 65 66 74 5b 6e 4c 65 66 74 2b      aLeft[nLeft+
2ab80 2b 5d 20 3d 20 70 53 65 67 3b 0a 0a 20 20 20 20  +] = pSeg;..    
2ab90 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 4c 65    for(i=0; i<pLe
2aba0 76 65 6c 2d 3e 6e 52 69 67 68 74 3b 20 69 2b 2b  vel->nRight; i++
2abb0 29 7b 0a 20 20 20 20 20 20 20 20 61 52 69 67 68  ){.        aRigh
2abc0 74 5b 6e 52 69 67 68 74 2b 2b 5d 20 3d 20 26 70  t[nRight++] = &p
2abd0 4c 65 76 65 6c 2d 3e 61 52 68 73 5b 69 5d 3b 0a  Level->aRhs[i];.
2abe0 20 20 20 20 20 20 7d 0a 0a 23 69 66 64 65 66 20        }..#ifdef 
2abf0 4c 53 4d 5f 4c 4f 47 5f 46 52 45 45 4c 49 53 54  LSM_LOG_FREELIST
2ac00 0a 20 20 20 20 20 20 69 66 28 20 6e 52 69 67 68  .      if( nRigh
2ac10 74 20 29 7b 0a 20 20 20 20 20 20 20 20 6d 65 6d  t ){.        mem
2ac20 6d 6f 76 65 28 26 61 52 69 67 68 74 5b 31 5d 2c  move(&aRight[1],
2ac30 20 61 52 69 67 68 74 2c 20 73 69 7a 65 6f 66 28   aRight, sizeof(
2ac40 61 52 69 67 68 74 5b 30 5d 29 2a 6e 52 69 67 68  aRight[0])*nRigh
2ac50 74 29 3b 0a 20 20 20 20 20 20 20 20 61 52 69 67  t);.        aRig
2ac60 68 74 5b 30 5d 20 3d 20 30 3b 0a 20 20 20 20 20  ht[0] = 0;.     
2ac70 20 20 20 6e 52 69 67 68 74 2b 2b 3b 0a 20 20 20     nRight++;.   
2ac80 20 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 20     }.#endif..   
2ac90 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 4c     for(i=0; i<nL
2aca0 65 66 74 20 7c 7c 20 69 3c 6e 52 69 67 68 74 3b  eft || i<nRight;
2acb0 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69   i++){.        i
2acc0 6e 74 20 69 50 61 64 20 3d 20 30 3b 0a 20 20 20  nt iPad = 0;.   
2acd0 20 20 20 20 20 63 68 61 72 20 7a 4c 65 76 65 6c       char zLevel
2ace0 5b 33 32 5d 3b 0a 20 20 20 20 20 20 20 20 7a 4c  [32];.        zL
2acf0 65 66 74 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 20  eft[0] = '\0';. 
2ad00 20 20 20 20 20 20 20 7a 52 69 67 68 74 5b 30 5d         zRight[0]
2ad10 20 3d 20 27 5c 30 27 3b 0a 0a 20 20 20 20 20 20   = '\0';..      
2ad20 20 20 69 66 28 20 69 3c 6e 4c 65 66 74 20 29 7b    if( i<nLeft ){
2ad30 20 0a 20 20 20 20 20 20 20 20 20 20 66 69 6c 65   .          file
2ad40 54 6f 53 74 72 69 6e 67 28 70 44 62 2c 20 7a 4c  ToString(pDb, zL
2ad50 65 66 74 2c 20 73 69 7a 65 6f 66 28 7a 4c 65 66  eft, sizeof(zLef
2ad60 74 29 2c 20 32 34 2c 20 61 4c 65 66 74 5b 69 5d  t), 24, aLeft[i]
2ad70 29 3b 20 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  ); .        }.  
2ad80 20 20 20 20 20 20 69 66 28 20 69 3c 6e 52 69 67        if( i<nRig
2ad90 68 74 20 29 7b 20 0a 20 20 20 20 20 20 20 20 20  ht ){ .         
2ada0 20 66 69 6c 65 54 6f 53 74 72 69 6e 67 28 70 44   fileToString(pD
2adb0 62 2c 20 7a 52 69 67 68 74 2c 20 73 69 7a 65 6f  b, zRight, sizeo
2adc0 66 28 7a 52 69 67 68 74 29 2c 20 32 34 2c 20 61  f(zRight), 24, a
2add0 52 69 67 68 74 5b 69 5d 29 3b 20 0a 20 20 20 20  Right[i]); .    
2ade0 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 69      }..        i
2adf0 66 28 20 69 3d 3d 30 20 29 7b 0a 20 20 20 20 20  f( i==0 ){.     
2ae00 20 20 20 20 20 73 6e 70 72 69 6e 74 66 28 7a 4c       snprintf(zL
2ae10 65 76 65 6c 2c 20 73 69 7a 65 6f 66 28 7a 4c 65  evel, sizeof(zLe
2ae20 76 65 6c 29 2c 20 22 4c 25 64 3a 20 28 61 67 65  vel), "L%d: (age
2ae30 3d 25 64 29 20 28 66 6c 61 67 73 3d 25 2e 34 78  =%d) (flags=%.4x
2ae40 29 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  )",.            
2ae50 20 20 69 4c 65 76 65 6c 2c 20 28 69 6e 74 29 70    iLevel, (int)p
2ae60 4c 65 76 65 6c 2d 3e 69 41 67 65 2c 20 28 69 6e  Level->iAge, (in
2ae70 74 29 70 4c 65 76 65 6c 2d 3e 66 6c 61 67 73 0a  t)pLevel->flags.
2ae80 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20            );.   
2ae90 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
2aea0 20 20 20 20 20 20 7a 4c 65 76 65 6c 5b 30 5d 20        zLevel[0] 
2aeb0 3d 20 27 5c 30 27 3b 0a 20 20 20 20 20 20 20 20  = '\0';.        
2aec0 7d 0a 0a 20 20 20 20 20 20 20 20 69 66 28 20 6e  }..        if( n
2aed0 52 69 67 68 74 3d 3d 30 20 29 7b 0a 20 20 20 20  Right==0 ){.    
2aee0 20 20 20 20 20 20 69 50 61 64 20 3d 20 31 30 3b        iPad = 10;
2aef0 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  .        }..    
2af00 20 20 20 20 6c 73 6d 4c 6f 67 4d 65 73 73 61 67      lsmLogMessag
2af10 65 28 70 44 62 2c 20 4c 53 4d 5f 4f 4b 2c 20 22  e(pDb, LSM_OK, "
2af20 25 20 32 35 73 20 25 20 2a 73 25 20 2d 33 35 73  % 25s % *s% -35s
2af30 20 25 73 22 2c 20 0a 20 20 20 20 20 20 20 20 20   %s", .         
2af40 20 20 20 7a 4c 65 76 65 6c 2c 20 69 50 61 64 2c     zLevel, iPad,
2af50 20 22 22 2c 20 7a 4c 65 66 74 2c 20 7a 52 69 67   "", zLeft, zRig
2af60 68 74 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20  ht.        );.  
2af70 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 69 4c 65      }..      iLe
2af80 76 65 6c 2b 2b 3b 0a 20 20 20 20 7d 0a 0a 20 20  vel++;.    }..  
2af90 20 20 69 66 28 20 62 4b 65 79 73 20 29 7b 0a 20    if( bKeys ){. 
2afa0 20 20 20 20 20 66 6f 72 28 70 4c 65 76 65 6c 3d       for(pLevel=
2afb0 70 54 6f 70 4c 65 76 65 6c 3b 20 70 4c 65 76 65  pTopLevel; pLeve
2afc0 6c 3b 20 70 4c 65 76 65 6c 3d 70 4c 65 76 65 6c  l; pLevel=pLevel
2afd0 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20  ->pNext){.      
2afe0 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 20    int i;.       
2aff0 20 73 6f 72 74 65 64 44 75 6d 70 53 65 67 6d 65   sortedDumpSegme
2b000 6e 74 28 70 44 62 2c 20 26 70 4c 65 76 65 6c 2d  nt(pDb, &pLevel-
2b010 3e 6c 68 73 2c 20 62 56 61 6c 73 29 3b 0a 20 20  >lhs, bVals);.  
2b020 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69        for(i=0; i
2b030 3c 70 4c 65 76 65 6c 2d 3e 6e 52 69 67 68 74 3b  <pLevel->nRight;
2b040 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20   i++){.         
2b050 20 73 6f 72 74 65 64 44 75 6d 70 53 65 67 6d 65   sortedDumpSegme
2b060 6e 74 28 70 44 62 2c 20 26 70 4c 65 76 65 6c 2d  nt(pDb, &pLevel-
2b070 3e 61 52 68 73 5b 69 5d 2c 20 62 56 61 6c 73 29  >aRhs[i], bVals)
2b080 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
2b090 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20    }.    }.  }.. 
2b0a0 20 6c 73 6d 49 6e 66 6f 46 72 65 65 6c 69 73 74   lsmInfoFreelist
2b0b0 28 70 44 62 2c 20 26 7a 46 72 65 65 29 3b 0a 20  (pDb, &zFree);. 
2b0c0 20 6c 73 6d 4c 6f 67 4d 65 73 73 61 67 65 28 70   lsmLogMessage(p
2b0d0 44 62 2c 20 4c 53 4d 5f 4f 4b 2c 20 22 46 72 65  Db, LSM_OK, "Fre
2b0e0 65 6c 69 73 74 3a 20 25 73 22 2c 20 7a 46 72 65  elist: %s", zFre
2b0f0 65 29 3b 0a 20 20 6c 73 6d 46 72 65 65 28 70 44  e);.  lsmFree(pD
2b100 62 2d 3e 70 45 6e 76 2c 20 7a 46 72 65 65 29 3b  b->pEnv, zFree);
2b110 0a 0a 20 20 61 73 73 65 72 74 28 20 6c 73 6d 46  ..  assert( lsmF
2b120 73 49 6e 74 65 67 72 69 74 79 43 68 65 63 6b 28  sIntegrityCheck(
2b130 70 44 62 29 20 29 3b 0a 7d 0a 0a 76 6f 69 64 20  pDb) );.}..void 
2b140 6c 73 6d 53 6f 72 74 65 64 46 72 65 65 4c 65 76  lsmSortedFreeLev
2b150 65 6c 28 6c 73 6d 5f 65 6e 76 20 2a 70 45 6e 76  el(lsm_env *pEnv
2b160 2c 20 4c 65 76 65 6c 20 2a 70 4c 65 76 65 6c 29  , Level *pLevel)
2b170 7b 0a 20 20 4c 65 76 65 6c 20 2a 70 4e 65 78 74  {.  Level *pNext
2b180 3b 0a 20 20 4c 65 76 65 6c 20 2a 70 3b 0a 0a 20  ;.  Level *p;.. 
2b190 20 66 6f 72 28 70 3d 70 4c 65 76 65 6c 3b 20 70   for(p=pLevel; p
2b1a0 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20  ; p=pNext){.    
2b1b0 70 4e 65 78 74 20 3d 20 70 2d 3e 70 4e 65 78 74  pNext = p->pNext
2b1c0 3b 0a 20 20 20 20 73 6f 72 74 65 64 46 72 65 65  ;.    sortedFree
2b1d0 4c 65 76 65 6c 28 70 45 6e 76 2c 20 70 29 3b 0a  Level(pEnv, p);.
2b1e0 20 20 7d 0a 7d 0a 0a 76 6f 69 64 20 6c 73 6d 53    }.}..void lsmS
2b1f0 6f 72 74 65 64 53 61 76 65 54 72 65 65 43 75 72  ortedSaveTreeCur
2b200 73 6f 72 73 28 6c 73 6d 5f 64 62 20 2a 70 44 62  sors(lsm_db *pDb
2b210 29 7b 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72  ){.  MultiCursor
2b220 20 2a 70 43 73 72 3b 0a 20 20 66 6f 72 28 70 43   *pCsr;.  for(pC
2b230 73 72 3d 70 44 62 2d 3e 70 43 73 72 3b 20 70 43  sr=pDb->pCsr; pC
2b240 73 72 3b 20 70 43 73 72 3d 70 43 73 72 2d 3e 70  sr; pCsr=pCsr->p
2b250 4e 65 78 74 29 7b 0a 20 20 20 20 6c 73 6d 54 72  Next){.    lsmTr
2b260 65 65 43 75 72 73 6f 72 53 61 76 65 28 70 43 73  eeCursorSave(pCs
2b270 72 2d 3e 61 70 54 72 65 65 43 73 72 5b 30 5d 29  r->apTreeCsr[0])
2b280 3b 0a 20 20 20 20 6c 73 6d 54 72 65 65 43 75 72  ;.    lsmTreeCur
2b290 73 6f 72 53 61 76 65 28 70 43 73 72 2d 3e 61 70  sorSave(pCsr->ap
2b2a0 54 72 65 65 43 73 72 5b 31 5d 29 3b 0a 20 20 7d  TreeCsr[1]);.  }
2b2b0 0a 7d 0a 0a 76 6f 69 64 20 6c 73 6d 53 6f 72 74  .}..void lsmSort
2b2c0 65 64 45 78 70 61 6e 64 42 74 72 65 65 50 61 67  edExpandBtreePag
2b2d0 65 28 50 61 67 65 20 2a 70 50 67 2c 20 69 6e 74  e(Page *pPg, int
2b2e0 20 6e 4f 72 69 67 29 7b 0a 20 20 75 38 20 2a 61   nOrig){.  u8 *a
2b2f0 44 61 74 61 3b 0a 20 20 69 6e 74 20 6e 44 61 74  Data;.  int nDat
2b300 61 3b 0a 20 20 69 6e 74 20 6e 45 6e 74 72 79 3b  a;.  int nEntry;
2b310 0a 20 20 69 6e 74 20 69 48 64 72 3b 0a 0a 20 20  .  int iHdr;..  
2b320 61 44 61 74 61 20 3d 20 6c 73 6d 46 73 50 61 67  aData = lsmFsPag
2b330 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44 61 74  eData(pPg, &nDat
2b340 61 29 3b 0a 20 20 6e 45 6e 74 72 79 20 3d 20 70  a);.  nEntry = p
2b350 61 67 65 47 65 74 4e 52 65 63 28 61 44 61 74 61  ageGetNRec(aData
2b360 2c 20 6e 4f 72 69 67 29 3b 0a 20 20 69 48 64 72  , nOrig);.  iHdr
2b370 20 3d 20 53 45 47 4d 45 4e 54 5f 45 4f 46 28 6e   = SEGMENT_EOF(n
2b380 4f 72 69 67 2c 20 6e 45 6e 74 72 79 29 3b 0a 20  Orig, nEntry);. 
2b390 20 6d 65 6d 6d 6f 76 65 28 26 61 44 61 74 61 5b   memmove(&aData[
2b3a0 69 48 64 72 20 2b 20 28 6e 44 61 74 61 2d 6e 4f  iHdr + (nData-nO
2b3b0 72 69 67 29 5d 2c 20 26 61 44 61 74 61 5b 69 48  rig)], &aData[iH
2b3c0 64 72 5d 2c 20 6e 4f 72 69 67 2d 69 48 64 72 29  dr], nOrig-iHdr)
2b3d0 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 4c 53 4d 5f  ;.}..#ifdef LSM_
2b3e0 44 45 42 55 47 5f 45 58 50 45 4e 53 49 56 45 0a  DEBUG_EXPENSIVE.
2b3f0 73 74 61 74 69 63 20 76 6f 69 64 20 61 73 73 65  static void asse
2b400 72 74 52 75 6e 49 6e 4f 72 64 65 72 28 6c 73 6d  rtRunInOrder(lsm
2b410 5f 64 62 20 2a 70 44 62 2c 20 53 65 67 6d 65 6e  _db *pDb, Segmen
2b420 74 20 2a 70 53 65 67 29 7b 0a 20 20 50 61 67 65  t *pSeg){.  Page
2b430 20 2a 70 50 67 20 3d 20 30 3b 0a 20 20 42 6c 6f   *pPg = 0;.  Blo
2b440 62 20 62 6c 6f 62 31 20 3d 20 7b 30 2c 20 30 2c  b blob1 = {0, 0,
2b450 20 30 2c 20 30 7d 3b 0a 20 20 42 6c 6f 62 20 62   0, 0};.  Blob b
2b460 6c 6f 62 32 20 3d 20 7b 30 2c 20 30 2c 20 30 2c  lob2 = {0, 0, 0,
2b470 20 30 7d 3b 0a 0a 20 20 6c 73 6d 46 73 44 62 50   0};..  lsmFsDbP
2b480 61 67 65 47 65 74 28 70 44 62 2d 3e 70 46 53 2c  ageGet(pDb->pFS,
2b490 20 70 53 65 67 2c 20 70 53 65 67 2d 3e 69 46 69   pSeg, pSeg->iFi
2b4a0 72 73 74 2c 20 26 70 50 67 29 3b 0a 20 20 77 68  rst, &pPg);.  wh
2b4b0 69 6c 65 28 20 70 50 67 20 29 7b 0a 20 20 20 20  ile( pPg ){.    
2b4c0 75 38 20 2a 61 44 61 74 61 3b 20 69 6e 74 20 6e  u8 *aData; int n
2b4d0 44 61 74 61 3b 0a 20 20 20 20 50 61 67 65 20 2a  Data;.    Page *
2b4e0 70 4e 65 78 74 3b 0a 0a 20 20 20 20 61 44 61 74  pNext;..    aDat
2b4f0 61 20 3d 20 6c 73 6d 46 73 50 61 67 65 44 61 74  a = lsmFsPageDat
2b500 61 28 70 50 67 2c 20 26 6e 44 61 74 61 29 3b 0a  a(pPg, &nData);.
2b510 20 20 20 20 69 66 28 20 30 3d 3d 28 70 61 67 65      if( 0==(page
2b520 47 65 74 46 6c 61 67 73 28 61 44 61 74 61 2c 20  GetFlags(aData, 
2b530 6e 44 61 74 61 29 20 26 20 53 45 47 4d 45 4e 54  nData) & SEGMENT
2b540 5f 42 54 52 45 45 5f 46 4c 41 47 29 20 29 7b 0a  _BTREE_FLAG) ){.
2b550 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20        int i;.   
2b560 20 20 20 69 6e 74 20 6e 52 65 63 20 3d 20 70 61     int nRec = pa
2b570 67 65 47 65 74 4e 52 65 63 28 61 44 61 74 61 2c  geGetNRec(aData,
2b580 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20 66   nData);.      f
2b590 6f 72 28 69 3d 30 3b 20 69 3c 6e 52 65 63 3b 20  or(i=0; i<nRec; 
2b5a0 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69 6e  i++){.        in
2b5b0 74 20 69 54 6f 70 69 63 31 2c 20 69 54 6f 70 69  t iTopic1, iTopi
2b5c0 63 32 3b 0a 20 20 20 20 20 20 20 20 70 61 67 65  c2;.        page
2b5d0 47 65 74 4b 65 79 43 6f 70 79 28 70 44 62 2d 3e  GetKeyCopy(pDb->
2b5e0 70 45 6e 76 2c 20 70 53 65 67 2c 20 70 50 67 2c  pEnv, pSeg, pPg,
2b5f0 20 69 2c 20 26 69 54 6f 70 69 63 31 2c 20 26 62   i, &iTopic1, &b
2b600 6c 6f 62 31 29 3b 0a 0a 20 20 20 20 20 20 20 20  lob1);..        
2b610 69 66 28 20 69 3d 3d 30 20 26 26 20 62 6c 6f 62  if( i==0 && blob
2b620 32 2e 6e 44 61 74 61 20 29 7b 0a 20 20 20 20 20  2.nData ){.     
2b630 20 20 20 20 20 61 73 73 65 72 74 28 20 73 6f 72       assert( sor
2b640 74 65 64 4b 65 79 43 6f 6d 70 61 72 65 28 0a 20  tedKeyCompare(. 
2b650 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
2b660 44 62 2d 3e 78 43 6d 70 2c 20 69 54 6f 70 69 63  Db->xCmp, iTopic
2b670 32 2c 20 62 6c 6f 62 32 2e 70 44 61 74 61 2c 20  2, blob2.pData, 
2b680 62 6c 6f 62 32 2e 6e 44 61 74 61 2c 0a 20 20 20  blob2.nData,.   
2b690 20 20 20 20 20 20 20 20 20 20 20 20 20 69 54 6f               iTo
2b6a0 70 69 63 31 2c 20 62 6c 6f 62 31 2e 70 44 61 74  pic1, blob1.pDat
2b6b0 61 2c 20 62 6c 6f 62 31 2e 6e 44 61 74 61 0a 20  a, blob1.nData. 
2b6c0 20 20 20 20 20 20 20 20 20 29 3c 30 20 29 3b 0a           )<0 );.
2b6d0 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
2b6e0 20 20 20 69 66 28 20 69 3c 28 6e 52 65 63 2d 31     if( i<(nRec-1
2b6f0 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70  ) ){.          p
2b700 61 67 65 47 65 74 4b 65 79 43 6f 70 79 28 70 44  ageGetKeyCopy(pD
2b710 62 2d 3e 70 45 6e 76 2c 20 70 53 65 67 2c 20 70  b->pEnv, pSeg, p
2b720 50 67 2c 20 69 2b 31 2c 20 26 69 54 6f 70 69 63  Pg, i+1, &iTopic
2b730 32 2c 20 26 62 6c 6f 62 32 29 3b 0a 20 20 20 20  2, &blob2);.    
2b740 20 20 20 20 20 20 61 73 73 65 72 74 28 20 73 6f        assert( so
2b750 72 74 65 64 4b 65 79 43 6f 6d 70 61 72 65 28 0a  rtedKeyCompare(.
2b760 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2b770 70 44 62 2d 3e 78 43 6d 70 2c 20 69 54 6f 70 69  pDb->xCmp, iTopi
2b780 63 31 2c 20 62 6c 6f 62 31 2e 70 44 61 74 61 2c  c1, blob1.pData,
2b790 20 62 6c 6f 62 31 2e 6e 44 61 74 61 2c 0a 20 20   blob1.nData,.  
2b7a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 54                iT
2b7b0 6f 70 69 63 32 2c 20 62 6c 6f 62 32 2e 70 44 61  opic2, blob2.pDa
2b7c0 74 61 2c 20 62 6c 6f 62 32 2e 6e 44 61 74 61 0a  ta, blob2.nData.
2b7d0 20 20 20 20 20 20 20 20 20 20 29 3c 30 20 29 3b            )<0 );
2b7e0 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
2b7f0 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 6c 73   }.    }..    ls
2b800 6d 46 73 44 62 50 61 67 65 4e 65 78 74 28 70 53  mFsDbPageNext(pS
2b810 65 67 2c 20 70 50 67 2c 20 31 2c 20 26 70 4e 65  eg, pPg, 1, &pNe
2b820 78 74 29 3b 0a 20 20 20 20 6c 73 6d 46 73 50 61  xt);.    lsmFsPa
2b830 67 65 52 65 6c 65 61 73 65 28 70 50 67 29 3b 0a  geRelease(pPg);.
2b840 20 20 20 20 70 50 67 20 3d 20 70 4e 65 78 74 3b      pPg = pNext;
2b850 0a 20 20 7d 0a 0a 20 20 73 6f 72 74 65 64 42 6c  .  }..  sortedBl
2b860 6f 62 46 72 65 65 28 26 62 6c 6f 62 31 29 3b 0a  obFree(&blob1);.
2b870 20 20 73 6f 72 74 65 64 42 6c 6f 62 46 72 65 65    sortedBlobFree
2b880 28 26 62 6c 6f 62 32 29 3b 0a 7d 0a 23 65 6e 64  (&blob2);.}.#end
2b890 69 66 0a 0a 23 69 66 64 65 66 20 4c 53 4d 5f 44  if..#ifdef LSM_D
2b8a0 45 42 55 47 5f 45 58 50 45 4e 53 49 56 45 0a 2f  EBUG_EXPENSIVE./
2b8b0 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
2b8c0 6f 6e 20 69 73 20 6f 6e 6c 79 20 69 6e 63 6c 75  on is only inclu
2b8d0 64 65 64 20 69 6e 20 74 68 65 20 62 75 69 6c 64  ded in the build
2b8e0 20 69 66 20 4c 53 4d 5f 44 45 42 55 47 5f 45 58   if LSM_DEBUG_EX
2b8f0 50 45 4e 53 49 56 45 20 69 73 20 0a 2a 2a 20 64  PENSIVE is .** d
2b900 65 66 69 6e 65 64 2e 20 49 74 73 20 6f 6e 6c 79  efined. Its only
2b910 20 70 75 72 70 6f 73 65 20 69 73 20 74 6f 20 65   purpose is to e
2b920 76 61 6c 75 61 74 65 20 76 61 72 69 6f 75 73 20  valuate various 
2b930 61 73 73 65 72 74 28 29 20 73 74 61 74 65 6d 65  assert() stateme
2b940 6e 74 73 20 74 6f 20 0a 2a 2a 20 76 65 72 69 66  nts to .** verif
2b950 79 20 74 68 61 74 20 74 68 65 20 64 61 74 61 62  y that the datab
2b960 61 73 65 20 69 73 20 77 65 6c 6c 20 66 6f 72 6d  ase is well form
2b970 65 64 20 69 6e 20 63 65 72 74 61 69 6e 20 72 65  ed in certain re
2b980 73 70 65 63 74 73 2e 0a 2a 2a 0a 2a 2a 20 4d 6f  spects..**.** Mo
2b990 72 65 20 73 70 65 63 69 66 69 63 61 6c 6c 79 2c  re specifically,
2b9a0 20 69 74 20 63 68 65 63 6b 73 20 74 68 61 74 20   it checks that 
2b9b0 74 68 65 20 61 72 72 61 79 20 70 4f 6e 65 20 63  the array pOne c
2b9c0 6f 6e 74 61 69 6e 73 20 74 68 65 20 72 65 71 75  ontains the requ
2b9d0 69 72 65 64 20 0a 2a 2a 20 70 6f 69 6e 74 65 72  ired .** pointer
2b9e0 73 20 74 6f 20 70 54 77 6f 2e 20 41 72 72 61 79  s to pTwo. Array
2b9f0 20 70 54 77 6f 20 6d 75 73 74 20 62 65 20 61 20   pTwo must be a 
2ba00 6d 61 69 6e 20 61 72 72 61 79 2e 20 70 4f 6e 65  main array. pOne
2ba10 20 6d 61 79 20 62 65 20 65 69 74 68 65 72 20 61   may be either a
2ba20 20 0a 2a 2a 20 73 65 70 61 72 61 74 6f 72 73 20   .** separators 
2ba30 61 72 72 61 79 20 6f 72 20 61 6e 6f 74 68 65 72  array or another
2ba40 20 6d 61 69 6e 20 61 72 72 61 79 2e 20 49 66 20   main array. If 
2ba50 70 4f 6e 65 20 64 6f 65 73 20 6e 6f 74 20 63 6f  pOne does not co
2ba60 6e 74 61 69 6e 20 74 68 65 20 0a 2a 2a 20 63 6f  ntain the .** co
2ba70 72 72 65 63 74 20 73 65 74 20 6f 66 20 70 6f 69  rrect set of poi
2ba80 6e 74 65 72 73 2c 20 61 6e 20 61 73 73 65 72 74  nters, an assert
2ba90 28 29 20 73 74 61 74 65 6d 65 6e 74 20 66 61 69  () statement fai
2baa0 6c 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ls..*/.static in
2bab0 74 20 61 73 73 65 72 74 50 6f 69 6e 74 65 72 73  t assertPointers
2bac0 4f 6b 28 0a 20 20 6c 73 6d 5f 64 62 20 2a 70 44  Ok(.  lsm_db *pD
2bad0 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
2bae0 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
2baf0 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 53 65  e handle */.  Se
2bb00 67 6d 65 6e 74 20 2a 70 4f 6e 65 2c 20 20 20 20  gment *pOne,    
2bb10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2bb20 20 53 65 67 6d 65 6e 74 20 63 6f 6e 74 61 69 6e   Segment contain
2bb30 69 6e 67 20 70 6f 69 6e 74 65 72 73 20 2a 2f 0a  ing pointers */.
2bb40 20 20 53 65 67 6d 65 6e 74 20 2a 70 54 77 6f 2c    Segment *pTwo,
2bb50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2bb60 20 20 2f 2a 20 53 65 67 6d 65 6e 74 20 63 6f 6e    /* Segment con
2bb70 74 61 69 6e 69 6e 67 20 70 6f 69 6e 74 65 72 20  taining pointer 
2bb80 74 61 72 67 65 74 73 20 2a 2f 0a 20 20 69 6e 74  targets */.  int
2bb90 20 62 52 68 73 20 20 20 20 20 20 20 20 20 20 20   bRhs           
2bba0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2bbb0 54 72 75 65 20 69 66 20 70 54 77 6f 20 6d 61 79  True if pTwo may
2bbc0 20 68 61 76 65 20 62 65 65 6e 20 47 6f 62 62 6c   have been Gobbl
2bbd0 65 28 29 64 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  e()d */.){.  int
2bbe0 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20   rc = LSM_OK;   
2bbf0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2bc00 45 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 20 20  Error code */.  
2bc10 53 65 67 6d 65 6e 74 50 74 72 20 70 74 72 31 3b  SegmentPtr ptr1;
2bc20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2bc30 2f 2a 20 49 74 65 72 61 74 65 73 20 74 68 72 6f  /* Iterates thro
2bc40 75 67 68 20 70 4f 6e 65 20 2a 2f 0a 20 20 53 65  ugh pOne */.  Se
2bc50 67 6d 65 6e 74 50 74 72 20 70 74 72 32 3b 20 20  gmentPtr ptr2;  
2bc60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2bc70 20 49 74 65 72 61 74 65 73 20 74 68 72 6f 75 67   Iterates throug
2bc80 68 20 70 54 77 6f 20 2a 2f 0a 20 20 50 67 6e 6f  h pTwo */.  Pgno
2bc90 20 69 50 72 65 76 3b 0a 0a 20 20 61 73 73 65 72   iPrev;..  asser
2bca0 74 28 20 70 4f 6e 65 20 26 26 20 70 54 77 6f 20  t( pOne && pTwo 
2bcb0 29 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 70 74  );..  memset(&pt
2bcc0 72 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 74  r1, 0, sizeof(pt
2bcd0 72 31 29 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26  r1));.  memset(&
2bce0 70 74 72 32 2c 20 30 2c 20 73 69 7a 65 6f 66 28  ptr2, 0, sizeof(
2bcf0 70 74 72 31 29 29 3b 0a 20 20 70 74 72 31 2e 70  ptr1));.  ptr1.p
2bd00 53 65 67 20 3d 20 70 4f 6e 65 3b 0a 20 20 70 74  Seg = pOne;.  pt
2bd10 72 32 2e 70 53 65 67 20 3d 20 70 54 77 6f 3b 0a  r2.pSeg = pTwo;.
2bd20 20 20 73 65 67 6d 65 6e 74 50 74 72 45 6e 64 50    segmentPtrEndP
2bd30 61 67 65 28 70 44 62 2d 3e 70 46 53 2c 20 26 70  age(pDb->pFS, &p
2bd40 74 72 31 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20  tr1, 0, &rc);.  
2bd50 73 65 67 6d 65 6e 74 50 74 72 45 6e 64 50 61 67  segmentPtrEndPag
2bd60 65 28 70 44 62 2d 3e 70 46 53 2c 20 26 70 74 72  e(pDb->pFS, &ptr
2bd70 32 2c 20 30 2c 20 26 72 63 29 3b 0a 0a 20 20 2f  2, 0, &rc);..  /
2bd80 2a 20 43 68 65 63 6b 20 74 68 61 74 20 74 68 65  * Check that the
2bd90 20 66 6f 6f 74 65 72 20 70 6f 69 6e 74 65 72 20   footer pointer 
2bda0 6f 66 20 74 68 65 20 66 69 72 73 74 20 70 61 67  of the first pag
2bdb0 65 20 6f 66 20 70 4f 6e 65 20 70 6f 69 6e 74 73  e of pOne points
2bdc0 20 74 6f 0a 20 20 2a 2a 20 74 68 65 20 66 69 72   to.  ** the fir
2bdd0 73 74 20 70 61 67 65 20 6f 66 20 70 54 77 6f 2e  st page of pTwo.
2bde0 20 2a 2f 0a 20 20 69 50 72 65 76 20 3d 20 70 54   */.  iPrev = pT
2bdf0 77 6f 2d 3e 69 46 69 72 73 74 3b 0a 20 20 69 66  wo->iFirst;.  if
2be00 28 20 70 74 72 31 2e 69 50 74 72 21 3d 69 50 72  ( ptr1.iPtr!=iPr
2be10 65 76 20 26 26 20 21 62 52 68 73 20 29 7b 0a 20  ev && !bRhs ){. 
2be20 20 20 20 61 73 73 65 72 74 28 20 30 20 29 3b 0a     assert( 0 );.
2be30 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c    }..  if( rc==L
2be40 53 4d 5f 4f 4b 20 26 26 20 70 74 72 31 2e 6e 43  SM_OK && ptr1.nC
2be50 65 6c 6c 3e 30 20 29 7b 0a 20 20 20 20 72 63 20  ell>0 ){.    rc 
2be60 3d 20 73 65 67 6d 65 6e 74 50 74 72 4c 6f 61 64  = segmentPtrLoad
2be70 43 65 6c 6c 28 26 70 74 72 31 2c 20 30 29 3b 0a  Cell(&ptr1, 0);.
2be80 20 20 7d 0a 20 20 20 20 20 20 0a 20 20 77 68 69    }.      .  whi
2be90 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26  le( rc==LSM_OK &
2bea0 26 20 70 74 72 32 2e 70 50 67 20 29 7b 0a 20 20  & ptr2.pPg ){.  
2beb0 20 20 50 67 6e 6f 20 69 54 68 69 73 3b 0a 0a 20    Pgno iThis;.. 
2bec0 20 20 20 2f 2a 20 41 64 76 61 6e 63 65 20 74 6f     /* Advance to
2bed0 20 74 68 65 20 6e 65 78 74 20 70 61 67 65 20 6f   the next page o
2bee0 66 20 73 65 67 6d 65 6e 74 20 70 54 77 6f 20 74  f segment pTwo t
2bef0 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 61 74 20  hat contains at 
2bf00 6c 65 61 73 74 0a 20 20 20 20 2a 2a 20 6f 6e 65  least.    ** one
2bf10 20 63 65 6c 6c 2e 20 42 72 65 61 6b 20 6f 75 74   cell. Break out
2bf20 20 6f 66 20 74 68 65 20 6c 6f 6f 70 20 69 66 20   of the loop if 
2bf30 74 68 65 20 69 74 65 72 61 74 6f 72 20 72 65 61  the iterator rea
2bf40 63 68 65 73 20 45 4f 46 2e 20 20 2a 2f 0a 20 20  ches EOF.  */.  
2bf50 20 20 64 6f 7b 0a 20 20 20 20 20 20 72 63 20 3d    do{.      rc =
2bf60 20 73 65 67 6d 65 6e 74 50 74 72 4e 65 78 74 50   segmentPtrNextP
2bf70 61 67 65 28 26 70 74 72 32 2c 20 31 29 3b 0a 20  age(&ptr2, 1);. 
2bf80 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63 3d       assert( rc=
2bf90 3d 4c 53 4d 5f 4f 4b 20 29 3b 0a 20 20 20 20 7d  =LSM_OK );.    }
2bfa0 77 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f  while( rc==LSM_O
2bfb0 4b 20 26 26 20 70 74 72 32 2e 70 50 67 20 26 26  K && ptr2.pPg &&
2bfc0 20 70 74 72 32 2e 6e 43 65 6c 6c 3d 3d 30 20 29   ptr2.nCell==0 )
2bfd0 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 4c 53  ;.    if( rc!=LS
2bfe0 4d 5f 4f 4b 20 7c 7c 20 70 74 72 32 2e 70 50 67  M_OK || ptr2.pPg
2bff0 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  ==0 ) break;.   
2c000 20 69 54 68 69 73 20 3d 20 6c 73 6d 46 73 50 61   iThis = lsmFsPa
2c010 67 65 4e 75 6d 62 65 72 28 70 74 72 32 2e 70 50  geNumber(ptr2.pP
2c020 67 29 3b 0a 0a 20 20 20 20 69 66 28 20 28 70 74  g);..    if( (pt
2c030 72 32 2e 66 6c 61 67 73 20 26 20 28 50 47 46 54  r2.flags & (PGFT
2c040 52 5f 53 4b 49 50 5f 54 48 49 53 5f 46 4c 41 47  R_SKIP_THIS_FLAG
2c050 7c 53 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46  |SEGMENT_BTREE_F
2c060 4c 41 47 29 29 3d 3d 30 20 29 7b 0a 0a 20 20 20  LAG))==0 ){..   
2c070 20 20 20 2f 2a 20 4c 6f 61 64 20 74 68 65 20 66     /* Load the f
2c080 69 72 73 74 20 63 65 6c 6c 20 69 6e 20 74 68 65  irst cell in the
2c090 20 61 72 72 61 79 20 70 54 77 6f 20 70 61 67 65   array pTwo page
2c0a0 2e 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20  . */.      rc = 
2c0b0 73 65 67 6d 65 6e 74 50 74 72 4c 6f 61 64 43 65  segmentPtrLoadCe
2c0c0 6c 6c 28 26 70 74 72 32 2c 20 30 29 3b 0a 0a 20  ll(&ptr2, 0);.. 
2c0d0 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74 65 20       /* Iterate 
2c0e0 66 6f 72 77 61 72 64 73 20 74 68 72 6f 75 67 68  forwards through
2c0f0 20 70 4f 6e 65 2c 20 73 65 61 72 63 68 69 6e 67   pOne, searching
2c100 20 66 6f 72 20 61 20 6b 65 79 20 74 68 61 74 20   for a key that 
2c110 6d 61 74 63 68 65 73 20 74 68 65 0a 20 20 20 20  matches the.    
2c120 20 20 2a 2a 20 6b 65 79 20 70 74 72 32 2e 70 4b    ** key ptr2.pK
2c130 65 79 2f 6e 4b 65 79 2e 20 54 68 69 73 20 6b 65  ey/nKey. This ke
2c140 79 20 73 68 6f 75 6c 64 20 68 61 76 65 20 61 20  y should have a 
2c150 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 70  pointer to the p
2c160 61 67 65 20 74 68 61 74 0a 20 20 20 20 20 20 2a  age that.      *
2c170 2a 20 70 74 72 32 20 63 75 72 72 65 6e 74 6c 79  * ptr2 currently
2c180 20 70 6f 69 6e 74 73 20 74 6f 2e 20 2a 2f 0a 20   points to. */. 
2c190 20 20 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d       while( rc==
2c1a0 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  LSM_OK ){.      
2c1b0 20 20 69 6e 74 20 72 65 73 20 3d 20 72 74 54 6f    int res = rtTo
2c1c0 70 69 63 28 70 74 72 31 2e 65 54 79 70 65 29 20  pic(ptr1.eType) 
2c1d0 2d 20 72 74 54 6f 70 69 63 28 70 74 72 32 2e 65  - rtTopic(ptr2.e
2c1e0 54 79 70 65 29 3b 0a 20 20 20 20 20 20 20 20 69  Type);.        i
2c1f0 66 28 20 72 65 73 3d 3d 30 20 29 7b 0a 20 20 20  f( res==0 ){.   
2c200 20 20 20 20 20 20 20 72 65 73 20 3d 20 70 44 62         res = pDb
2c210 2d 3e 78 43 6d 70 28 70 74 72 31 2e 70 4b 65 79  ->xCmp(ptr1.pKey
2c220 2c 20 70 74 72 31 2e 6e 4b 65 79 2c 20 70 74 72  , ptr1.nKey, ptr
2c230 32 2e 70 4b 65 79 2c 20 70 74 72 32 2e 6e 4b 65  2.pKey, ptr2.nKe
2c240 79 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20  y);.        }.. 
2c250 20 20 20 20 20 20 20 69 66 28 20 72 65 73 3c 30         if( res<0
2c260 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 61 73   ){.          as
2c270 73 65 72 74 28 20 62 52 68 73 20 7c 7c 20 70 74  sert( bRhs || pt
2c280 72 31 2e 69 50 74 72 2b 70 74 72 31 2e 69 50 67  r1.iPtr+ptr1.iPg
2c290 50 74 72 3d 3d 69 50 72 65 76 20 29 3b 0a 20 20  Ptr==iPrev );.  
2c2a0 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
2c2b0 72 65 73 3e 30 20 29 7b 0a 20 20 20 20 20 20 20  res>0 ){.       
2c2c0 20 20 20 61 73 73 65 72 74 28 20 30 20 29 3b 0a     assert( 0 );.
2c2d0 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
2c2e0 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
2c2f0 20 70 74 72 31 2e 69 50 74 72 2b 70 74 72 31 2e   ptr1.iPtr+ptr1.
2c300 69 50 67 50 74 72 3d 3d 69 54 68 69 73 20 29 3b  iPgPtr==iThis );
2c310 0a 20 20 20 20 20 20 20 20 20 20 69 50 72 65 76  .          iPrev
2c320 20 3d 20 69 54 68 69 73 3b 0a 20 20 20 20 20 20   = iThis;.      
2c330 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
2c340 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 72 63     }..        rc
2c350 20 3d 20 73 65 67 6d 65 6e 74 50 74 72 41 64 76   = segmentPtrAdv
2c360 61 6e 63 65 28 30 2c 20 26 70 74 72 31 2c 20 30  ance(0, &ptr1, 0
2c370 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  );.        if( p
2c380 74 72 31 2e 70 50 67 3d 3d 30 20 29 7b 0a 20 20  tr1.pPg==0 ){.  
2c390 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
2c3a0 30 20 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  0 );.        }. 
2c3b0 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
2c3c0 0a 0a 20 20 73 65 67 6d 65 6e 74 50 74 72 52 65  ..  segmentPtrRe
2c3d0 73 65 74 28 26 70 74 72 31 2c 20 30 29 3b 0a 20  set(&ptr1, 0);. 
2c3e0 20 73 65 67 6d 65 6e 74 50 74 72 52 65 73 65 74   segmentPtrReset
2c3f0 28 26 70 74 72 32 2c 20 30 29 3b 0a 20 20 72 65  (&ptr2, 0);.  re
2c400 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 7d 0a 0a  turn LSM_OK;.}..
2c410 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
2c420 69 6f 6e 20 69 73 20 6f 6e 6c 79 20 69 6e 63 6c  ion is only incl
2c430 75 64 65 64 20 69 6e 20 74 68 65 20 62 75 69 6c  uded in the buil
2c440 64 20 69 66 20 4c 53 4d 5f 44 45 42 55 47 5f 45  d if LSM_DEBUG_E
2c450 58 50 45 4e 53 49 56 45 20 69 73 20 0a 2a 2a 20  XPENSIVE is .** 
2c460 64 65 66 69 6e 65 64 2e 20 49 74 73 20 6f 6e 6c  defined. Its onl
2c470 79 20 70 75 72 70 6f 73 65 20 69 73 20 74 6f 20  y purpose is to 
2c480 65 76 61 6c 75 61 74 65 20 76 61 72 69 6f 75 73  evaluate various
2c490 20 61 73 73 65 72 74 28 29 20 73 74 61 74 65 6d   assert() statem
2c4a0 65 6e 74 73 20 74 6f 20 0a 2a 2a 20 76 65 72 69  ents to .** veri
2c4b0 66 79 20 74 68 61 74 20 74 68 65 20 64 61 74 61  fy that the data
2c4c0 62 61 73 65 20 69 73 20 77 65 6c 6c 20 66 6f 72  base is well for
2c4d0 6d 65 64 20 69 6e 20 63 65 72 74 61 69 6e 20 72  med in certain r
2c4e0 65 73 70 65 63 74 73 2e 0a 2a 2a 0a 2a 2a 20 4d  espects..**.** M
2c4f0 6f 72 65 20 73 70 65 63 69 66 69 63 61 6c 6c 79  ore specifically
2c500 2c 20 69 74 20 63 68 65 63 6b 73 20 74 68 61 74  , it checks that
2c510 20 74 68 65 20 62 2d 74 72 65 65 20 65 6d 62 65   the b-tree embe
2c520 64 64 65 64 20 69 6e 20 61 72 72 61 79 20 70 52  dded in array pR
2c530 75 6e 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 74  un.** contains t
2c540 68 65 20 63 6f 72 72 65 63 74 20 6b 65 79 73 2e  he correct keys.
2c550 20 49 66 20 6e 6f 74 2c 20 61 6e 20 61 73 73 65   If not, an asse
2c560 72 74 28 29 20 66 61 69 6c 73 2e 0a 2a 2f 0a 73  rt() fails..*/.s
2c570 74 61 74 69 63 20 69 6e 74 20 61 73 73 65 72 74  tatic int assert
2c580 42 74 72 65 65 4f 6b 28 0a 20 20 6c 73 6d 5f 64  BtreeOk(.  lsm_d
2c590 62 20 2a 70 44 62 2c 0a 20 20 53 65 67 6d 65 6e  b *pDb,.  Segmen
2c5a0 74 20 2a 70 53 65 67 0a 29 7b 0a 20 20 69 6e 74  t *pSeg.){.  int
2c5b0 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20   rc = LSM_OK;   
2c5c0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2c5d0 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
2c5e0 20 69 66 28 20 70 53 65 67 2d 3e 69 52 6f 6f 74   if( pSeg->iRoot
2c5f0 20 29 7b 0a 20 20 20 20 42 6c 6f 62 20 62 6c 6f   ){.    Blob blo
2c600 62 20 3d 20 7b 30 2c 20 30 2c 20 30 7d 3b 20 20  b = {0, 0, 0};  
2c610 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
2c620 75 73 65 64 20 74 6f 20 63 61 63 68 65 20 6f 76  used to cache ov
2c630 65 72 66 6c 6f 77 20 6b 65 79 73 20 2a 2f 0a 20  erflow keys */. 
2c640 20 20 20 46 69 6c 65 53 79 73 74 65 6d 20 2a 70     FileSystem *p
2c650 46 53 20 3d 20 70 44 62 2d 3e 70 46 53 3b 20 20  FS = pDb->pFS;  
2c660 20 2f 2a 20 46 69 6c 65 20 73 79 73 74 65 6d 20   /* File system 
2c670 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a  to read from */.
2c680 20 20 20 20 50 61 67 65 20 2a 70 50 67 20 3d 20      Page *pPg = 
2c690 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
2c6a0 20 20 2f 2a 20 4d 61 69 6e 20 72 75 6e 20 70 61    /* Main run pa
2c6b0 67 65 20 2a 2f 0a 20 20 20 20 42 74 72 65 65 43  ge */.    BtreeC
2c6c0 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 30 3b  ursor *pCsr = 0;
2c6d0 20 20 20 20 20 20 20 20 2f 2a 20 42 74 72 65 65          /* Btree
2c6e0 20 63 75 72 73 6f 72 20 2a 2f 0a 0a 20 20 20 20   cursor */..    
2c6f0 72 63 20 3d 20 62 74 72 65 65 43 75 72 73 6f 72  rc = btreeCursor
2c700 4e 65 77 28 70 44 62 2c 20 70 53 65 67 2c 20 26  New(pDb, pSeg, &
2c710 70 43 73 72 29 3b 0a 20 20 20 20 69 66 28 20 72  pCsr);.    if( r
2c720 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
2c730 20 20 20 72 63 20 3d 20 62 74 72 65 65 43 75 72     rc = btreeCur
2c740 73 6f 72 46 69 72 73 74 28 70 43 73 72 29 3b 0a  sorFirst(pCsr);.
2c750 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63      }.    if( rc
2c760 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20  ==LSM_OK ){.    
2c770 20 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50 61    rc = lsmFsDbPa
2c780 67 65 47 65 74 28 70 46 53 2c 20 70 53 65 67 2c  geGet(pFS, pSeg,
2c790 20 70 53 65 67 2d 3e 69 46 69 72 73 74 2c 20 26   pSeg->iFirst, &
2c7a0 70 50 67 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  pPg);.    }..   
2c7b0 20 77 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f   while( rc==LSM_
2c7c0 4f 4b 20 29 7b 0a 20 20 20 20 20 20 50 61 67 65  OK ){.      Page
2c7d0 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 75   *pNext;.      u
2c7e0 38 20 2a 61 44 61 74 61 3b 0a 20 20 20 20 20 20  8 *aData;.      
2c7f0 69 6e 74 20 6e 44 61 74 61 3b 0a 20 20 20 20 20  int nData;.     
2c800 20 69 6e 74 20 66 6c 61 67 73 3b 0a 0a 20 20 20   int flags;..   
2c810 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50     rc = lsmFsDbP
2c820 61 67 65 4e 65 78 74 28 70 53 65 67 2c 20 70 50  ageNext(pSeg, pP
2c830 67 2c 20 31 2c 20 26 70 4e 65 78 74 29 3b 0a 20  g, 1, &pNext);. 
2c840 20 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65       lsmFsPageRe
2c850 6c 65 61 73 65 28 70 50 67 29 3b 0a 20 20 20 20  lease(pPg);.    
2c860 20 20 70 50 67 20 3d 20 70 4e 65 78 74 3b 0a 20    pPg = pNext;. 
2c870 20 20 20 20 20 69 66 28 20 70 50 67 3d 3d 30 20       if( pPg==0 
2c880 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 61  ) break;.      a
2c890 44 61 74 61 20 3d 20 66 73 50 61 67 65 44 61 74  Data = fsPageDat
2c8a0 61 28 70 50 67 2c 20 26 6e 44 61 74 61 29 3b 0a  a(pPg, &nData);.
2c8b0 20 20 20 20 20 20 66 6c 61 67 73 20 3d 20 70 61        flags = pa
2c8c0 67 65 47 65 74 46 6c 61 67 73 28 61 44 61 74 61  geGetFlags(aData
2c8d0 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20  , nData);.      
2c8e0 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 0a  if( rc==LSM_OK .
2c8f0 20 20 20 20 20 20 20 26 26 20 30 3d 3d 28 28 53         && 0==((S
2c900 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41  EGMENT_BTREE_FLA
2c910 47 7c 50 47 46 54 52 5f 53 4b 49 50 5f 54 48 49  G|PGFTR_SKIP_THI
2c920 53 5f 46 4c 41 47 29 20 26 20 66 6c 61 67 73 29  S_FLAG) & flags)
2c930 0a 20 20 20 20 20 20 20 26 26 20 30 21 3d 70 61  .       && 0!=pa
2c940 67 65 47 65 74 4e 52 65 63 28 61 44 61 74 61 2c  geGetNRec(aData,
2c950 20 6e 44 61 74 61 29 0a 20 20 20 20 20 20 29 7b   nData).      ){
2c960 0a 20 20 20 20 20 20 20 20 75 38 20 2a 70 4b 65  .        u8 *pKe
2c970 79 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e  y;.        int n
2c980 4b 65 79 3b 0a 20 20 20 20 20 20 20 20 69 6e 74  Key;.        int
2c990 20 69 54 6f 70 69 63 3b 0a 20 20 20 20 20 20 20   iTopic;.       
2c9a0 20 70 4b 65 79 20 3d 20 70 61 67 65 47 65 74 4b   pKey = pageGetK
2c9b0 65 79 28 70 53 65 67 2c 20 70 50 67 2c 20 30 2c  ey(pSeg, pPg, 0,
2c9c0 20 26 69 54 6f 70 69 63 2c 20 26 6e 4b 65 79 2c   &iTopic, &nKey,
2c9d0 20 26 62 6c 6f 62 29 3b 0a 20 20 20 20 20 20 20   &blob);.       
2c9e0 20 61 73 73 65 72 74 28 20 6e 4b 65 79 3d 3d 70   assert( nKey==p
2c9f0 43 73 72 2d 3e 6e 4b 65 79 20 26 26 20 30 3d 3d  Csr->nKey && 0==
2ca00 6d 65 6d 63 6d 70 28 70 4b 65 79 2c 20 70 43 73  memcmp(pKey, pCs
2ca10 72 2d 3e 70 4b 65 79 2c 20 6e 4b 65 79 29 20 29  r->pKey, nKey) )
2ca20 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  ;.        assert
2ca30 28 20 6c 73 6d 46 73 50 61 67 65 4e 75 6d 62 65  ( lsmFsPageNumbe
2ca40 72 28 70 50 67 29 3d 3d 70 43 73 72 2d 3e 69 50  r(pPg)==pCsr->iP
2ca50 74 72 20 29 3b 0a 20 20 20 20 20 20 20 20 72 63  tr );.        rc
2ca60 20 3d 20 62 74 72 65 65 43 75 72 73 6f 72 4e 65   = btreeCursorNe
2ca70 78 74 28 70 43 73 72 29 3b 0a 20 20 20 20 20 20  xt(pCsr);.      
2ca80 7d 0a 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65  }.    }.    asse
2ca90 72 74 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c  rt( rc!=LSM_OK |
2caa0 7c 20 70 43 73 72 2d 3e 70 4b 65 79 3d 3d 30 20  | pCsr->pKey==0 
2cab0 29 3b 0a 0a 20 20 20 20 69 66 28 20 70 50 67 20  );..    if( pPg 
2cac0 29 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61  ) lsmFsPageRelea
2cad0 73 65 28 70 50 67 29 3b 0a 0a 20 20 20 20 62 74  se(pPg);..    bt
2cae0 72 65 65 43 75 72 73 6f 72 46 72 65 65 28 70 43  reeCursorFree(pC
2caf0 73 72 29 3b 0a 20 20 20 20 73 6f 72 74 65 64 42  sr);.    sortedB
2cb00 6c 6f 62 46 72 65 65 28 26 62 6c 6f 62 29 3b 0a  lobFree(&blob);.
2cb10 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
2cb20 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 69 66  ;.}.#endif /* if
2cb30 64 65 66 20 4c 53 4d 5f 44 45 42 55 47 5f 45 58  def LSM_DEBUG_EX
2cb40 50 45 4e 53 49 56 45 20 2a 2f 0a                 PENSIVE */.