/ Hex Artifact Content
Login

Artifact 6f7d8cf7a7d3d3f1ab5d9ba6347e8f39f3d73c00ec48afcd0c4bcbefd806f9b8:


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: 2d 31 29 0a 0a 23 64 65 66 69 6e 65 20 53 45 47  -1)..#define SEG
0df0: 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 20  MENT_BTREE_FLAG 
0e00: 20 20 20 20 30 78 30 30 30 31 0a 23 64 65 66 69      0x0001.#defi
0e10: 6e 65 20 50 47 46 54 52 5f 53 4b 49 50 5f 4e 45  ne PGFTR_SKIP_NE
0e20: 58 54 5f 46 4c 41 47 20 20 20 30 78 30 30 30 32  XT_FLAG   0x0002
0e30: 0a 23 64 65 66 69 6e 65 20 50 47 46 54 52 5f 53  .#define PGFTR_S
0e40: 4b 49 50 5f 54 48 49 53 5f 46 4c 41 47 20 20 20  KIP_THIS_FLAG   
0e50: 30 78 30 30 30 34 0a 0a 0a 23 69 66 6e 64 65 66  0x0004...#ifndef
0e60: 20 4c 53 4d 5f 53 45 47 4d 45 4e 54 50 54 52 5f   LSM_SEGMENTPTR_
0e70: 46 52 45 45 5f 54 48 52 45 53 48 4f 4c 44 0a 23  FREE_THRESHOLD.#
0e80: 20 64 65 66 69 6e 65 20 4c 53 4d 5f 53 45 47 4d   define LSM_SEGM
0e90: 45 4e 54 50 54 52 5f 46 52 45 45 5f 54 48 52 45  ENTPTR_FREE_THRE
0ea0: 53 48 4f 4c 44 20 31 30 32 34 0a 23 65 6e 64 69  SHOLD 1024.#endi
0eb0: 66 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  f..typedef struc
0ec0: 74 20 53 65 67 6d 65 6e 74 50 74 72 20 53 65 67  t SegmentPtr Seg
0ed0: 6d 65 6e 74 50 74 72 3b 0a 74 79 70 65 64 65 66  mentPtr;.typedef
0ee0: 20 73 74 72 75 63 74 20 4c 73 6d 42 6c 6f 62 20   struct LsmBlob 
0ef0: 4c 73 6d 42 6c 6f 62 3b 0a 0a 73 74 72 75 63 74  LsmBlob;..struct
0f00: 20 4c 73 6d 42 6c 6f 62 20 7b 0a 20 20 6c 73 6d   LsmBlob {.  lsm
0f10: 5f 65 6e 76 20 2a 70 45 6e 76 3b 0a 20 20 76 6f  _env *pEnv;.  vo
0f20: 69 64 20 2a 70 44 61 74 61 3b 0a 20 20 69 6e 74  id *pData;.  int
0f30: 20 6e 44 61 74 61 3b 0a 20 20 69 6e 74 20 6e 41   nData;.  int nA
0f40: 6c 6c 6f 63 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  lloc;.};../*.** 
0f50: 41 20 53 65 67 6d 65 6e 74 50 74 72 20 6f 62 6a  A SegmentPtr obj
0f60: 65 63 74 20 6d 61 79 20 62 65 20 75 73 65 64 20  ect may be used 
0f70: 66 6f 72 20 6f 6e 65 20 6f 66 20 74 77 6f 20 70  for one of two p
0f80: 75 72 70 6f 73 65 73 3a 0a 2a 2a 0a 2a 2a 20 20  urposes:.**.**  
0f90: 20 2a 20 54 6f 20 69 74 65 72 61 74 65 20 61 6e   * To iterate an
0fa0: 64 2f 6f 72 20 73 65 65 6b 20 77 69 74 68 69 6e  d/or seek within
0fb0: 20 61 20 73 69 6e 67 6c 65 20 53 65 67 6d 65 6e   a single Segmen
0fc0: 74 20 28 74 68 65 20 63 6f 6d 62 69 6e 61 74 69  t (the combinati
0fd0: 6f 6e 20 6f 66 20 61 20 0a 2a 2a 20 20 20 20 20  on of a .**     
0fe0: 6d 61 69 6e 20 72 75 6e 20 61 6e 64 20 61 6e 20  main run and an 
0ff0: 6f 70 74 69 6f 6e 61 6c 20 73 6f 72 74 65 64 20  optional sorted 
1000: 72 75 6e 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 2a 20  run)..**.**   * 
1010: 54 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75  To iterate throu
1020: 67 68 20 74 68 65 20 73 65 70 61 72 61 74 6f 72  gh the separator
1030: 73 20 61 72 72 61 79 20 6f 66 20 61 20 73 65 67  s array of a seg
1040: 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  ment..*/.struct 
1050: 53 65 67 6d 65 6e 74 50 74 72 20 7b 0a 20 20 4c  SegmentPtr {.  L
1060: 65 76 65 6c 20 2a 70 4c 65 76 65 6c 3b 20 20 20  evel *pLevel;   
1070: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1080: 4c 65 76 65 6c 20 6f 62 6a 65 63 74 20 73 65 67  Level object seg
1090: 6d 65 6e 74 20 69 73 20 70 61 72 74 20 6f 66 20  ment is part of 
10a0: 2a 2f 0a 20 20 53 65 67 6d 65 6e 74 20 2a 70 53  */.  Segment *pS
10b0: 65 67 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  eg;             
10c0: 20 20 20 2f 2a 20 53 65 67 6d 65 6e 74 20 74 6f     /* Segment to
10d0: 20 61 63 63 65 73 73 20 2a 2f 0a 0a 20 20 2f 2a   access */..  /*
10e0: 20 43 75 72 72 65 6e 74 20 70 61 67 65 2e 20 53   Current page. S
10f0: 65 65 20 73 65 67 6d 65 6e 74 50 74 72 4c 6f 61  ee segmentPtrLoa
1100: 64 50 61 67 65 28 29 2e 20 2a 2f 0a 20 20 50 61  dPage(). */.  Pa
1110: 67 65 20 2a 70 50 67 3b 20 20 20 20 20 20 20 20  ge *pPg;        
1120: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
1130: 75 72 72 65 6e 74 20 70 61 67 65 20 2a 2f 0a 20  urrent page */. 
1140: 20 75 31 36 20 66 6c 61 67 73 3b 20 20 20 20 20   u16 flags;     
1150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1160: 2a 20 43 6f 70 79 20 6f 66 20 70 61 67 65 20 66  * Copy of page f
1170: 6c 61 67 73 20 66 69 65 6c 64 20 2a 2f 0a 20 20  lags field */.  
1180: 69 6e 74 20 6e 43 65 6c 6c 3b 20 20 20 20 20 20  int nCell;      
1190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
11a0: 20 4e 75 6d 62 65 72 20 6f 66 20 63 65 6c 6c 73   Number of cells
11b0: 20 6f 6e 20 70 50 67 20 2a 2f 0a 20 20 4c 73 6d   on pPg */.  Lsm
11c0: 50 67 6e 6f 20 69 50 74 72 3b 20 20 20 20 20 20  Pgno iPtr;      
11d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 61             /* Ba
11e0: 73 65 20 63 61 73 63 61 64 65 20 70 6f 69 6e 74  se cascade point
11f0: 65 72 20 2a 2f 0a 0a 20 20 2f 2a 20 43 75 72 72  er */..  /* Curr
1200: 65 6e 74 20 63 65 6c 6c 2e 20 53 65 65 20 73 65  ent cell. See se
1210: 67 6d 65 6e 74 50 74 72 4c 6f 61 64 43 65 6c 6c  gmentPtrLoadCell
1220: 28 29 20 2a 2f 0a 20 20 69 6e 74 20 69 43 65 6c  () */.  int iCel
1230: 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l;              
1240: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
1250: 20 72 65 63 6f 72 64 20 77 69 74 68 69 6e 20 70   record within p
1260: 61 67 65 20 70 50 67 20 2a 2f 0a 20 20 69 6e 74  age pPg */.  int
1270: 20 65 54 79 70 65 3b 20 20 20 20 20 20 20 20 20   eType;         
1280: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 79             /* Ty
1290: 70 65 20 6f 66 20 63 75 72 72 65 6e 74 20 72 65  pe of current re
12a0: 63 6f 72 64 20 2a 2f 0a 20 20 4c 73 6d 50 67 6e  cord */.  LsmPgn
12b0: 6f 20 69 50 67 50 74 72 3b 20 20 20 20 20 20 20  o iPgPtr;       
12c0: 20 20 20 20 20 20 20 20 2f 2a 20 43 61 73 63 61          /* Casca
12d0: 64 65 20 70 6f 69 6e 74 65 72 20 6f 66 66 73 65  de pointer offse
12e0: 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 4b 65  t */.  void *pKe
12f0: 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20 20  y; int nKey;    
1300: 20 20 20 20 20 2f 2a 20 4b 65 79 20 61 73 73 6f       /* Key asso
1310: 63 69 61 74 65 64 20 77 69 74 68 20 63 75 72 72  ciated with curr
1320: 65 6e 74 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20  ent record */.  
1330: 76 6f 69 64 20 2a 70 56 61 6c 3b 20 69 6e 74 20  void *pVal; int 
1340: 6e 56 61 6c 3b 20 20 20 20 20 20 20 20 20 2f 2a  nVal;         /*
1350: 20 43 75 72 72 65 6e 74 20 72 65 63 6f 72 64 20   Current record 
1360: 76 61 6c 75 65 20 28 65 54 79 70 65 3d 3d 57 52  value (eType==WR
1370: 49 54 45 20 6f 6e 6c 79 29 20 2a 2f 0a 0a 20 20  ITE only) */..  
1380: 2f 2a 20 42 6c 6f 62 73 20 75 73 65 64 20 74 6f  /* Blobs used to
1390: 20 61 6c 6c 6f 63 61 74 65 20 62 75 66 66 65 72   allocate buffer
13a0: 73 20 66 6f 72 20 70 4b 65 79 20 61 6e 64 20 70  s for pKey and p
13b0: 56 61 6c 20 61 73 20 72 65 71 75 69 72 65 64 20  Val as required 
13c0: 2a 2f 0a 20 20 4c 73 6d 42 6c 6f 62 20 62 6c 6f  */.  LsmBlob blo
13d0: 62 31 3b 0a 20 20 4c 73 6d 42 6c 6f 62 20 62 6c  b1;.  LsmBlob bl
13e0: 6f 62 32 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 55  ob2;.};../*.** U
13f0: 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74  sed to iterate t
1400: 68 72 6f 75 67 68 20 74 68 65 20 6b 65 79 73 20  hrough the keys 
1410: 73 74 6f 72 65 64 20 69 6e 20 61 20 62 2d 74 72  stored in a b-tr
1420: 65 65 20 68 69 65 72 61 72 63 68 79 20 66 72 6f  ee hierarchy fro
1430: 6d 20 73 74 61 72 74 0a 2a 2a 20 74 6f 20 66 69  m start.** to fi
1440: 6e 69 73 68 2e 20 4f 6e 6c 79 20 46 69 72 73 74  nish. Only First
1450: 28 29 20 61 6e 64 20 4e 65 78 74 28 29 20 6f 70  () and Next() op
1460: 65 72 61 74 69 6f 6e 73 20 61 72 65 20 72 65 71  erations are req
1470: 75 69 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 62  uired..**.**   b
1480: 74 72 65 65 43 75 72 73 6f 72 4e 65 77 28 29 0a  treeCursorNew().
1490: 2a 2a 20 20 20 62 74 72 65 65 43 75 72 73 6f 72  **   btreeCursor
14a0: 46 69 72 73 74 28 29 0a 2a 2a 20 20 20 62 74 72  First().**   btr
14b0: 65 65 43 75 72 73 6f 72 4e 65 78 74 28 29 0a 2a  eeCursorNext().*
14c0: 2a 20 20 20 62 74 72 65 65 43 75 72 73 6f 72 46  *   btreeCursorF
14d0: 72 65 65 28 29 0a 2a 2a 20 20 20 62 74 72 65 65  ree().**   btree
14e0: 43 75 72 73 6f 72 50 6f 73 69 74 69 6f 6e 28 29  CursorPosition()
14f0: 0a 2a 2a 20 20 20 62 74 72 65 65 43 75 72 73 6f  .**   btreeCurso
1500: 72 52 65 73 74 6f 72 65 28 29 0a 2a 2f 0a 74 79  rRestore().*/.ty
1510: 70 65 64 65 66 20 73 74 72 75 63 74 20 42 74 72  pedef struct Btr
1520: 65 65 50 67 20 42 74 72 65 65 50 67 3b 0a 74 79  eePg BtreePg;.ty
1530: 70 65 64 65 66 20 73 74 72 75 63 74 20 42 74 72  pedef struct Btr
1540: 65 65 43 75 72 73 6f 72 20 42 74 72 65 65 43 75  eeCursor BtreeCu
1550: 72 73 6f 72 3b 0a 73 74 72 75 63 74 20 42 74 72  rsor;.struct Btr
1560: 65 65 50 67 20 7b 0a 20 20 50 61 67 65 20 2a 70  eePg {.  Page *p
1570: 50 61 67 65 3b 0a 20 20 69 6e 74 20 69 43 65 6c  Page;.  int iCel
1580: 6c 3b 0a 7d 3b 0a 73 74 72 75 63 74 20 42 74 72  l;.};.struct Btr
1590: 65 65 43 75 72 73 6f 72 20 7b 0a 20 20 53 65 67  eeCursor {.  Seg
15a0: 6d 65 6e 74 20 2a 70 53 65 67 3b 20 20 20 20 20  ment *pSeg;     
15b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
15c0: 49 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20  Iterate through 
15d0: 74 68 69 73 20 73 65 67 6d 65 6e 74 73 20 62 74  this segments bt
15e0: 72 65 65 20 2a 2f 0a 20 20 46 69 6c 65 53 79 73  ree */.  FileSys
15f0: 74 65 6d 20 2a 70 46 53 3b 20 20 20 20 20 20 20  tem *pFS;       
1600: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65           /* File
1610: 20 73 79 73 74 65 6d 20 74 6f 20 72 65 61 64 20   system to read 
1620: 70 61 67 65 73 20 66 72 6f 6d 20 2a 2f 0a 20 20  pages from */.  
1630: 69 6e 74 20 6e 44 65 70 74 68 3b 20 20 20 20 20  int nDepth;     
1640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1650: 2f 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73 69 7a  /* Allocated siz
1660: 65 20 6f 66 20 61 50 67 5b 5d 20 2a 2f 0a 20 20  e of aPg[] */.  
1670: 69 6e 74 20 69 50 67 3b 20 20 20 20 20 20 20 20  int iPg;        
1680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1690: 2f 2a 20 43 75 72 72 65 6e 74 20 65 6e 74 72 79  /* Current entry
16a0: 20 69 6e 20 61 50 67 5b 5d 2e 20 2d 31 20 2d 3e   in aPg[]. -1 ->
16b0: 20 45 4f 46 2e 20 2a 2f 0a 20 20 42 74 72 65 65   EOF. */.  Btree
16c0: 50 67 20 2a 61 50 67 3b 20 20 20 20 20 20 20 20  Pg *aPg;        
16d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
16e0: 67 65 73 20 66 72 6f 6d 20 72 6f 6f 74 20 74 6f  ges from root to
16f0: 20 63 75 72 72 65 6e 74 20 6c 6f 63 61 74 69 6f   current locatio
1700: 6e 20 2a 2f 0a 0a 20 20 2f 2a 20 43 61 63 68 65  n */..  /* Cache
1710: 20 6f 66 20 63 75 72 72 65 6e 74 20 65 6e 74 72   of current entr
1720: 79 2e 20 70 4b 65 79 3d 3d 30 20 66 6f 72 20 45  y. pKey==0 for E
1730: 4f 46 2e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  OF. */.  void *p
1740: 4b 65 79 3b 0a 20 20 69 6e 74 20 6e 4b 65 79 3b  Key;.  int nKey;
1750: 0a 20 20 69 6e 74 20 65 54 79 70 65 3b 0a 20 20  .  int eType;.  
1760: 4c 73 6d 50 67 6e 6f 20 69 50 74 72 3b 0a 0a 20  LsmPgno iPtr;.. 
1770: 20 2f 2a 20 53 74 6f 72 61 67 65 20 66 6f 72 20   /* Storage for 
1780: 6b 65 79 2c 20 69 66 20 6e 6f 74 20 6c 6f 63 61  key, if not loca
1790: 6c 20 2a 2f 0a 20 20 4c 73 6d 42 6c 6f 62 20 62  l */.  LsmBlob b
17a0: 6c 6f 62 3b 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20  lob;.};.../*.** 
17b0: 41 20 63 75 72 73 6f 72 20 75 73 65 64 20 66 6f  A cursor used fo
17c0: 72 20 6d 65 72 67 65 64 20 73 65 61 72 63 68 65  r merged searche
17d0: 73 20 6f 72 20 69 74 65 72 61 74 69 6f 6e 73 20  s or iterations 
17e0: 74 68 72 6f 75 67 68 20 75 70 20 74 6f 20 6f 6e  through up to on
17f0: 65 0a 2a 2a 20 54 72 65 65 20 73 74 72 75 63 74  e.** Tree struct
1800: 75 72 65 20 61 6e 64 20 61 6e 79 20 6e 75 6d 62  ure and any numb
1810: 65 72 20 6f 66 20 73 6f 72 74 65 64 20 66 69 6c  er of sorted fil
1820: 65 73 2e 0a 2a 2a 0a 2a 2a 20 20 20 6c 73 6d 4d  es..**.**   lsmM
1830: 43 75 72 73 6f 72 4e 65 77 28 29 0a 2a 2a 20 20  CursorNew().**  
1840: 20 6c 73 6d 4d 43 75 72 73 6f 72 53 65 65 6b 28   lsmMCursorSeek(
1850: 29 0a 2a 2a 20 20 20 6c 73 6d 4d 43 75 72 73 6f  ).**   lsmMCurso
1860: 72 4e 65 78 74 28 29 0a 2a 2a 20 20 20 6c 73 6d  rNext().**   lsm
1870: 4d 43 75 72 73 6f 72 50 72 65 76 28 29 0a 2a 2a  MCursorPrev().**
1880: 20 20 20 6c 73 6d 4d 43 75 72 73 6f 72 46 69 72     lsmMCursorFir
1890: 73 74 28 29 0a 2a 2a 20 20 20 6c 73 6d 4d 43 75  st().**   lsmMCu
18a0: 72 73 6f 72 4c 61 73 74 28 29 0a 2a 2a 20 20 20  rsorLast().**   
18b0: 6c 73 6d 4d 43 75 72 73 6f 72 4b 65 79 28 29 0a  lsmMCursorKey().
18c0: 2a 2a 20 20 20 6c 73 6d 4d 43 75 72 73 6f 72 56  **   lsmMCursorV
18d0: 61 6c 75 65 28 29 0a 2a 2a 20 20 20 6c 73 6d 4d  alue().**   lsmM
18e0: 43 75 72 73 6f 72 56 61 6c 69 64 28 29 0a 2a 2a  CursorValid().**
18f0: 0a 2a 2a 20 69 46 72 65 65 3a 0a 2a 2a 20 20 20  .** iFree:.**   
1900: 54 68 69 73 20 76 61 72 69 61 62 6c 65 20 69 73  This variable is
1910: 20 6f 6e 6c 79 20 75 73 65 64 20 62 79 20 63 75   only used by cu
1920: 72 73 6f 72 73 20 70 72 6f 76 69 64 69 6e 67 20  rsors providing 
1930: 69 6e 70 75 74 20 64 61 74 61 20 66 6f 72 20 61  input data for a
1940: 0a 2a 2a 20 20 20 6e 65 77 20 74 6f 70 2d 6c 65  .**   new top-le
1950: 76 65 6c 20 73 65 67 6d 65 6e 74 2e 20 53 75 63  vel segment. Suc
1960: 68 20 63 75 72 73 6f 72 73 20 6f 6e 6c 79 20 65  h cursors only e
1970: 76 65 72 20 69 74 65 72 61 74 65 20 66 6f 72 77  ver iterate forw
1980: 61 72 64 73 2c 20 6e 6f 74 0a 2a 2a 20 20 20 62  ards, not.**   b
1990: 61 63 6b 77 61 72 64 73 2e 0a 2a 2f 0a 73 74 72  ackwards..*/.str
19a0: 75 63 74 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  uct MultiCursor 
19b0: 7b 0a 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62 3b  {.  lsm_db *pDb;
19c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19d0: 20 20 20 20 2f 2a 20 43 6f 6e 6e 65 63 74 69 6f      /* Connectio
19e0: 6e 20 74 68 61 74 20 6f 77 6e 73 20 74 68 69 73  n that owns this
19f0: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 4d 75 6c   cursor */.  Mul
1a00: 74 69 43 75 72 73 6f 72 20 2a 70 4e 65 78 74 3b  tiCursor *pNext;
1a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1a20: 4e 65 78 74 20 63 75 72 73 6f 72 20 6f 77 6e 65  Next cursor owne
1a30: 64 20 62 79 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  d by connection 
1a40: 70 44 62 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61  pDb */.  int fla
1a50: 67 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  gs;             
1a60: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 73 6b           /* Mask
1a70: 20 6f 66 20 43 55 52 53 4f 52 5f 58 58 58 20 66   of CURSOR_XXX f
1a80: 6c 61 67 73 20 2a 2f 0a 0a 20 20 69 6e 74 20 65  lags */..  int e
1a90: 54 79 70 65 3b 20 20 20 20 20 20 20 20 20 20 20  Type;           
1aa0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61             /* Ca
1ab0: 63 68 65 20 6f 66 20 63 75 72 72 65 6e 74 20 6b  che of current k
1ac0: 65 79 20 74 79 70 65 20 2a 2f 0a 20 20 4c 73 6d  ey type */.  Lsm
1ad0: 42 6c 6f 62 20 6b 65 79 3b 20 20 20 20 20 20 20  Blob key;       
1ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1af0: 43 61 63 68 65 20 6f 66 20 63 75 72 72 65 6e 74  Cache of current
1b00: 20 6b 65 79 20 28 6f 72 20 4e 55 4c 4c 29 20 2a   key (or NULL) *
1b10: 2f 0a 20 20 4c 73 6d 42 6c 6f 62 20 76 61 6c 3b  /.  LsmBlob val;
1b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b30: 20 20 20 20 2f 2a 20 43 61 63 68 65 20 6f 66 20      /* Cache of 
1b40: 63 75 72 72 65 6e 74 20 76 61 6c 75 65 20 2a 2f  current value */
1b50: 0a 0a 20 20 2f 2a 20 41 6c 6c 20 74 68 65 20 63  ..  /* All the c
1b60: 6f 6d 70 6f 6e 65 6e 74 20 63 75 72 73 6f 72 73  omponent cursors
1b70: 3a 20 2a 2f 0a 20 20 54 72 65 65 43 75 72 73 6f  : */.  TreeCurso
1b80: 72 20 2a 61 70 54 72 65 65 43 73 72 5b 32 5d 3b  r *apTreeCsr[2];
1b90: 20 20 20 20 20 20 20 2f 2a 20 55 70 20 74 6f 20         /* Up to 
1ba0: 74 77 6f 20 74 72 65 65 20 63 75 72 73 6f 72 73  two tree cursors
1bb0: 20 2a 2f 0a 20 20 69 6e 74 20 69 46 72 65 65 3b   */.  int iFree;
1bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bd0: 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 65 6c        /* Next el
1be0: 65 6d 65 6e 74 20 6f 66 20 66 72 65 65 2d 6c 69  ement of free-li
1bf0: 73 74 20 28 2d 76 65 20 66 6f 72 20 65 6f 66 29  st (-ve for eof)
1c00: 20 2a 2f 0a 20 20 53 65 67 6d 65 6e 74 50 74 72   */.  SegmentPtr
1c10: 20 2a 61 50 74 72 3b 20 20 20 20 20 20 20 20 20   *aPtr;         
1c20: 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
1c30: 66 20 73 65 67 6d 65 6e 74 20 70 6f 69 6e 74 65  f segment pointe
1c40: 72 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 74 72  rs */.  int nPtr
1c50: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1c60: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
1c70: 6f 66 20 61 72 72 61 79 20 61 50 74 72 5b 5d 20  of array aPtr[] 
1c80: 2a 2f 0a 20 20 42 74 72 65 65 43 75 72 73 6f 72  */.  BtreeCursor
1c90: 20 2a 70 42 74 43 73 72 3b 20 20 20 20 20 20 20   *pBtCsr;       
1ca0: 20 20 20 20 20 2f 2a 20 62 2d 74 72 65 65 20 63       /* b-tree c
1cb0: 75 72 73 6f 72 20 28 64 62 20 77 72 69 74 65 73  ursor (db writes
1cc0: 20 6f 6e 6c 79 29 20 2a 2f 0a 0a 20 20 2f 2a 20   only) */..  /* 
1cd0: 43 6f 6d 70 61 72 69 73 6f 6e 20 72 65 73 75 6c  Comparison resul
1ce0: 74 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 72 65  ts */.  int nTre
1cf0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
1d00: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
1d10: 6f 66 20 61 54 72 65 65 5b 5d 20 61 72 72 61 79  of aTree[] array
1d20: 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 54 72 65 65   */.  int *aTree
1d30: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1d40: 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
1d50: 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 72 65 73  f comparison res
1d60: 75 6c 74 73 20 2a 2f 0a 0a 20 20 2f 2a 20 55 73  ults */..  /* Us
1d70: 65 64 20 62 79 20 63 75 72 73 6f 72 73 20 66 6c  ed by cursors fl
1d80: 75 73 68 69 6e 67 20 74 68 65 20 69 6e 2d 6d 65  ushing the in-me
1d90: 6d 6f 72 79 20 74 72 65 65 20 6f 6e 6c 79 20 2a  mory tree only *
1da0: 2f 0a 20 20 76 6f 69 64 20 2a 70 53 79 73 74 65  /.  void *pSyste
1db0: 6d 56 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20  mVal;           
1dc0: 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
1dd0: 6f 20 62 75 66 66 65 72 20 74 6f 20 66 72 65 65  o buffer to free
1de0: 20 2a 2f 0a 0a 20 20 2f 2a 20 55 73 65 64 20 62   */..  /* Used b
1df0: 79 20 77 6f 72 6b 65 72 20 63 75 72 73 6f 72 73  y worker cursors
1e00: 20 6f 6e 6c 79 20 2a 2f 0a 20 20 4c 73 6d 50 67   only */.  LsmPg
1e10: 6e 6f 20 2a 70 50 72 65 76 4d 65 72 67 65 50 74  no *pPrevMergePt
1e20: 72 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  r;.};../*.** The
1e30: 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f 6e 73 74   following const
1e40: 61 6e 74 73 20 61 72 65 20 75 73 65 64 20 74 6f  ants are used to
1e50: 20 61 73 73 69 67 6e 20 69 6e 74 65 67 65 72 73   assign integers
1e60: 20 74 6f 20 65 61 63 68 20 63 6f 6d 70 6f 6e 65   to each compone
1e70: 6e 74 0a 2a 2a 20 63 75 72 73 6f 72 20 6f 66 20  nt.** cursor of 
1e80: 61 20 6d 75 6c 74 69 2d 63 75 72 73 6f 72 2e 0a  a multi-cursor..
1e90: 2a 2f 0a 23 64 65 66 69 6e 65 20 43 55 52 53 4f  */.#define CURSO
1ea0: 52 5f 44 41 54 41 5f 54 52 45 45 30 20 20 20 20  R_DATA_TREE0    
1eb0: 20 30 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20   0   /* Current 
1ec0: 74 72 65 65 20 63 75 72 73 6f 72 20 28 61 70 54  tree cursor (apT
1ed0: 72 65 65 43 73 72 5b 30 5d 29 20 2a 2f 0a 23 64  reeCsr[0]) */.#d
1ee0: 65 66 69 6e 65 20 43 55 52 53 4f 52 5f 44 41 54  efine CURSOR_DAT
1ef0: 41 5f 54 52 45 45 31 20 20 20 20 20 31 20 20 20  A_TREE1     1   
1f00: 2f 2a 20 54 68 65 20 22 6f 6c 64 22 20 74 72 65  /* The "old" tre
1f10: 65 2c 20 69 66 20 61 6e 79 20 28 61 70 54 72 65  e, if any (apTre
1f20: 65 43 73 72 5b 31 5d 29 20 2a 2f 0a 23 64 65 66  eCsr[1]) */.#def
1f30: 69 6e 65 20 43 55 52 53 4f 52 5f 44 41 54 41 5f  ine CURSOR_DATA_
1f40: 53 59 53 54 45 4d 20 20 20 20 32 20 20 20 2f 2a  SYSTEM    2   /*
1f50: 20 46 72 65 65 2d 6c 69 73 74 20 65 6e 74 72 69   Free-list entri
1f60: 65 73 20 28 6e 65 77 2d 74 6f 70 6c 65 76 65 6c  es (new-toplevel
1f70: 20 6f 6e 6c 79 29 20 2a 2f 0a 23 64 65 66 69 6e   only) */.#defin
1f80: 65 20 43 55 52 53 4f 52 5f 44 41 54 41 5f 53 45  e CURSOR_DATA_SE
1f90: 47 4d 45 4e 54 20 20 20 33 20 20 20 2f 2a 20 46  GMENT   3   /* F
1fa0: 69 72 73 74 20 73 65 67 6d 65 6e 74 20 70 6f 69  irst segment poi
1fb0: 6e 74 65 72 20 28 61 50 74 72 5b 30 5d 29 20 2a  nter (aPtr[0]) *
1fc0: 2f 0a 0a 2f 2a 0a 2a 2a 20 43 55 52 53 4f 52 5f  /../*.** CURSOR_
1fd0: 49 47 4e 4f 52 45 5f 44 45 4c 45 54 45 0a 2a 2a  IGNORE_DELETE.**
1fe0: 20 20 20 49 66 20 73 65 74 2c 20 74 68 69 73 20     If set, this 
1ff0: 63 75 72 73 6f 72 20 77 69 6c 6c 20 6e 6f 74 20  cursor will not 
2000: 76 69 73 69 74 20 53 4f 52 54 45 44 5f 44 45 4c  visit SORTED_DEL
2010: 45 54 45 20 6b 65 79 73 2e 0a 2a 2a 0a 2a 2a 20  ETE keys..**.** 
2020: 43 55 52 53 4f 52 5f 46 4c 55 53 48 5f 46 52 45  CURSOR_FLUSH_FRE
2030: 45 4c 49 53 54 0a 2a 2a 20 20 20 54 68 69 73 20  ELIST.**   This 
2040: 63 75 72 73 6f 72 20 69 73 20 62 65 69 6e 67 20  cursor is being 
2050: 75 73 65 64 20 74 6f 20 63 72 65 61 74 65 20 61  used to create a
2060: 20 6e 65 77 20 74 6f 70 6c 65 76 65 6c 2e 20 49   new toplevel. I
2070: 74 20 73 68 6f 75 6c 64 20 61 6c 73 6f 20 0a 2a  t should also .*
2080: 2a 20 20 20 69 74 65 72 61 74 65 20 74 68 72 6f  *   iterate thro
2090: 75 67 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  ugh the contents
20a0: 20 6f 66 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72   of the in-memor
20b0: 79 20 66 72 65 65 20 62 6c 6f 63 6b 20 6c 69 73  y free block lis
20c0: 74 2e 0a 2a 2a 0a 2a 2a 20 43 55 52 53 4f 52 5f  t..**.** CURSOR_
20d0: 49 47 4e 4f 52 45 5f 53 59 53 54 45 4d 0a 2a 2a  IGNORE_SYSTEM.**
20e0: 20 20 20 49 66 20 73 65 74 2c 20 74 68 69 73 20     If set, this 
20f0: 63 75 72 73 6f 72 20 69 67 6e 6f 72 65 73 20 73  cursor ignores s
2100: 79 73 74 65 6d 20 6b 65 79 73 2e 0a 2a 2a 0a 2a  ystem keys..**.*
2110: 2a 20 43 55 52 53 4f 52 5f 4e 45 58 54 5f 4f 4b  * CURSOR_NEXT_OK
2120: 0a 2a 2a 20 20 20 53 65 74 20 69 66 20 69 74 20  .**   Set if it 
2130: 69 73 20 4f 6b 20 74 6f 20 63 61 6c 6c 20 6c 73  is Ok to call ls
2140: 6d 5f 63 73 72 5f 6e 65 78 74 28 29 2e 0a 2a 2a  m_csr_next()..**
2150: 0a 2a 2a 20 43 55 52 53 4f 52 5f 50 52 45 56 5f  .** CURSOR_PREV_
2160: 4f 4b 0a 2a 2a 20 20 20 53 65 74 20 69 66 20 69  OK.**   Set if i
2170: 74 20 69 73 20 4f 6b 20 74 6f 20 63 61 6c 6c 20  t is Ok to call 
2180: 6c 73 6d 5f 63 73 72 5f 70 72 65 76 28 29 2e 0a  lsm_csr_prev()..
2190: 2a 2a 0a 2a 2a 20 43 55 52 53 4f 52 5f 52 45 41  **.** CURSOR_REA
21a0: 44 5f 53 45 50 41 52 41 54 4f 52 53 0a 2a 2a 20  D_SEPARATORS.** 
21b0: 20 20 53 65 74 20 69 66 20 74 68 69 73 20 63 75    Set if this cu
21c0: 72 73 6f 72 20 73 68 6f 75 6c 64 20 76 69 73 69  rsor should visi
21d0: 74 20 74 68 65 20 73 65 70 61 72 61 74 6f 72 20  t the separator 
21e0: 6b 65 79 73 20 69 6e 20 73 65 67 6d 65 6e 74 20  keys in segment 
21f0: 0a 2a 2a 20 20 20 61 50 74 72 5b 6e 50 74 72 2d  .**   aPtr[nPtr-
2200: 31 5d 2e 0a 2a 2a 0a 2a 2a 20 43 55 52 53 4f 52  1]..**.** CURSOR
2210: 5f 53 45 45 4b 5f 45 51 0a 2a 2a 20 20 20 43 75  _SEEK_EQ.**   Cu
2220: 72 73 6f 72 20 68 61 73 20 75 6e 64 65 72 67 6f  rsor has undergo
2230: 6e 65 20 61 20 73 75 63 63 65 73 73 66 75 6c 20  ne a successful 
2240: 6c 73 6d 5f 63 73 72 5f 73 65 65 6b 28 4c 53 4d  lsm_csr_seek(LSM
2250: 5f 53 45 45 4b 5f 45 51 29 20 6f 70 65 72 61 74  _SEEK_EQ) operat
2260: 69 6f 6e 2e 0a 2a 2a 20 20 20 54 68 65 20 6b 65  ion..**   The ke
2270: 79 20 61 6e 64 20 76 61 6c 75 65 20 61 72 65 20  y and value are 
2280: 73 74 6f 72 65 64 20 69 6e 20 4d 75 6c 74 69 43  stored in MultiC
2290: 75 72 73 6f 72 2e 6b 65 79 20 61 6e 64 20 4d 75  ursor.key and Mu
22a0: 6c 74 69 43 75 72 73 6f 72 2e 76 61 6c 0a 2a 2a  ltiCursor.val.**
22b0: 20 20 20 72 65 73 70 65 63 74 69 76 65 6c 79 2e     respectively.
22c0: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 43 55 52 53  .*/.#define CURS
22d0: 4f 52 5f 49 47 4e 4f 52 45 5f 44 45 4c 45 54 45  OR_IGNORE_DELETE
22e0: 20 20 20 20 30 78 30 30 30 30 30 30 30 31 0a 23      0x00000001.#
22f0: 64 65 66 69 6e 65 20 43 55 52 53 4f 52 5f 46 4c  define CURSOR_FL
2300: 55 53 48 5f 46 52 45 45 4c 49 53 54 20 20 20 30  USH_FREELIST   0
2310: 78 30 30 30 30 30 30 30 32 0a 23 64 65 66 69 6e  x00000002.#defin
2320: 65 20 43 55 52 53 4f 52 5f 49 47 4e 4f 52 45 5f  e CURSOR_IGNORE_
2330: 53 59 53 54 45 4d 20 20 20 20 30 78 30 30 30 30  SYSTEM    0x0000
2340: 30 30 31 30 0a 23 64 65 66 69 6e 65 20 43 55 52  0010.#define CUR
2350: 53 4f 52 5f 4e 45 58 54 5f 4f 4b 20 20 20 20 20  SOR_NEXT_OK     
2360: 20 20 20 20 20 30 78 30 30 30 30 30 30 32 30 0a       0x00000020.
2370: 23 64 65 66 69 6e 65 20 43 55 52 53 4f 52 5f 50  #define CURSOR_P
2380: 52 45 56 5f 4f 4b 20 20 20 20 20 20 20 20 20 20  REV_OK          
2390: 30 78 30 30 30 30 30 30 34 30 0a 23 64 65 66 69  0x00000040.#defi
23a0: 6e 65 20 43 55 52 53 4f 52 5f 52 45 41 44 5f 53  ne CURSOR_READ_S
23b0: 45 50 41 52 41 54 4f 52 53 20 20 30 78 30 30 30  EPARATORS  0x000
23c0: 30 30 30 38 30 0a 23 64 65 66 69 6e 65 20 43 55  00080.#define CU
23d0: 52 53 4f 52 5f 53 45 45 4b 5f 45 51 20 20 20 20  RSOR_SEEK_EQ    
23e0: 20 20 20 20 20 20 30 78 30 30 30 30 30 31 30 30        0x00000100
23f0: 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ..typedef struct
2400: 20 4d 65 72 67 65 57 6f 72 6b 65 72 20 4d 65 72   MergeWorker Mer
2410: 67 65 57 6f 72 6b 65 72 3b 0a 74 79 70 65 64 65  geWorker;.typede
2420: 66 20 73 74 72 75 63 74 20 48 69 65 72 61 72 63  f struct Hierarc
2430: 68 79 20 48 69 65 72 61 72 63 68 79 3b 0a 0a 73  hy Hierarchy;..s
2440: 74 72 75 63 74 20 48 69 65 72 61 72 63 68 79 20  truct Hierarchy 
2450: 7b 0a 20 20 50 61 67 65 20 2a 2a 61 70 48 69 65  {.  Page **apHie
2460: 72 3b 0a 20 20 69 6e 74 20 6e 48 69 65 72 3b 0a  r;.  int nHier;.
2470: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 61 53 61 76 65 3a  };../*.** aSave:
2480: 0a 2a 2a 20 20 20 57 68 65 6e 20 6d 65 72 67 65  .**   When merge
2490: 57 6f 72 6b 65 72 4e 65 78 74 50 61 67 65 28 29  WorkerNextPage()
24a0: 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 61 64   is called to ad
24b0: 76 61 6e 63 65 20 74 6f 20 74 68 65 20 6e 65 78  vance to the nex
24c0: 74 20 70 61 67 65 20 69 6e 0a 2a 2a 20 20 20 74  t page in.**   t
24d0: 68 65 20 6f 75 74 70 75 74 20 73 65 67 6d 65 6e  he output segmen
24e0: 74 2c 20 69 66 20 74 68 65 20 62 53 74 6f 72 65  t, if the bStore
24f0: 20 66 6c 61 67 20 66 6f 72 20 61 6e 20 65 6c 65   flag for an ele
2500: 6d 65 6e 74 20 6f 66 20 61 53 61 76 65 5b 5d 20  ment of aSave[] 
2510: 69 73 0a 2a 2a 20 20 20 74 72 75 65 2c 20 69 74  is.**   true, it
2520: 20 69 73 20 63 6c 65 61 72 65 64 20 61 6e 64 20   is cleared and 
2530: 74 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e  the correspondin
2540: 67 20 69 50 67 6e 6f 20 76 61 6c 75 65 20 69 73  g iPgno value is
2550: 20 73 65 74 20 74 6f 20 74 68 65 20 0a 2a 2a 20   set to the .** 
2560: 20 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 66    page number of
2570: 20 74 68 65 20 70 61 67 65 20 6a 75 73 74 20 63   the page just c
2580: 6f 6d 70 6c 65 74 65 64 2e 0a 2a 2a 0a 2a 2a 20  ompleted..**.** 
2590: 20 20 61 53 61 76 65 5b 30 5d 20 69 73 20 75 73    aSave[0] is us
25a0: 65 64 20 74 6f 20 72 65 63 6f 72 64 20 74 68 65  ed to record the
25b0: 20 70 6f 69 6e 74 65 72 20 76 61 6c 75 65 20 74   pointer value t
25c0: 6f 20 62 65 20 70 75 73 68 65 64 20 69 6e 74 6f  o be pushed into
25d0: 20 74 68 65 0a 2a 2a 20 20 20 62 2d 74 72 65 65   the.**   b-tree
25e0: 20 68 69 65 72 61 72 63 68 79 2e 20 61 53 61 76   hierarchy. aSav
25f0: 65 5b 31 5d 20 69 73 20 75 73 65 64 20 74 6f 20  e[1] is used to 
2600: 73 61 76 65 20 74 68 65 20 70 61 67 65 20 6e 75  save the page nu
2610: 6d 62 65 72 20 6f 66 20 74 68 65 0a 2a 2a 20 20  mber of the.**  
2620: 20 70 61 67 65 20 63 6f 6e 74 61 69 6e 69 6e 67   page containing
2630: 20 74 68 65 20 69 6e 64 69 72 65 63 74 20 6b 65   the indirect ke
2640: 79 20 6d 6f 73 74 20 72 65 63 65 6e 74 6c 79 20  y most recently 
2650: 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20 62  written to the b
2660: 2d 74 72 65 65 2e 0a 2a 2a 20 20 20 73 65 65 20  -tree..**   see 
2670: 6d 65 72 67 65 57 6f 72 6b 65 72 50 75 73 68 48  mergeWorkerPushH
2680: 69 65 72 61 72 63 68 79 28 29 20 66 6f 72 20 64  ierarchy() for d
2690: 65 74 61 69 6c 73 2e 0a 2a 2f 0a 73 74 72 75 63  etails..*/.struc
26a0: 74 20 4d 65 72 67 65 57 6f 72 6b 65 72 20 7b 0a  t MergeWorker {.
26b0: 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62 3b 20 20    lsm_db *pDb;  
26c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26d0: 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61    /* Database ha
26e0: 6e 64 6c 65 20 2a 2f 0a 20 20 4c 65 76 65 6c 20  ndle */.  Level 
26f0: 2a 70 4c 65 76 65 6c 3b 20 20 20 20 20 20 20 20  *pLevel;        
2700: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 6f 72            /* Wor
2710: 6b 65 72 20 73 6e 61 70 73 68 6f 74 20 4c 65 76  ker snapshot Lev
2720: 65 6c 20 62 65 69 6e 67 20 6d 65 72 67 65 64 20  el being merged 
2730: 2a 2f 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72  */.  MultiCursor
2740: 20 2a 70 43 73 72 3b 20 20 20 20 20 20 20 20 20   *pCsr;         
2750: 20 20 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 74       /* Cursor t
2760: 6f 20 72 65 61 64 20 6e 65 77 20 73 65 67 6d 65  o read new segme
2770: 6e 74 20 63 6f 6e 74 65 6e 74 73 20 66 72 6f 6d  nt contents from
2780: 20 2a 2f 0a 20 20 69 6e 74 20 62 46 6c 75 73 68   */.  int bFlush
2790: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
27a0: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
27b0: 20 74 68 69 73 20 69 73 20 61 6e 20 69 6e 2d 6d   this is an in-m
27c0: 65 6d 6f 72 79 20 74 72 65 65 20 66 6c 75 73 68  emory tree flush
27d0: 20 2a 2f 0a 20 20 48 69 65 72 61 72 63 68 79 20   */.  Hierarchy 
27e0: 68 69 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  hier;           
27f0: 20 20 20 20 20 20 2f 2a 20 42 2d 74 72 65 65 20        /* B-tree 
2800: 68 69 65 72 61 72 63 68 79 20 75 6e 64 65 72 20  hierarchy under 
2810: 63 6f 6e 73 74 72 75 63 74 69 6f 6e 20 2a 2f 0a  construction */.
2820: 20 20 50 61 67 65 20 2a 70 50 61 67 65 3b 20 20    Page *pPage;  
2830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2840: 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 6f 75 74    /* Current out
2850: 70 75 74 20 70 61 67 65 20 2a 2f 0a 20 20 69 6e  put page */.  in
2860: 74 20 6e 57 6f 72 6b 3b 20 20 20 20 20 20 20 20  t nWork;        
2870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2880: 20 4e 75 6d 62 65 72 20 6f 66 20 63 61 6c 6c 73   Number of calls
2890: 20 74 6f 20 6d 65 72 67 65 57 6f 72 6b 65 72 4e   to mergeWorkerN
28a0: 65 78 74 50 61 67 65 28 29 20 2a 2f 0a 20 20 4c  extPage() */.  L
28b0: 73 6d 50 67 6e 6f 20 2a 61 47 6f 62 62 6c 65 3b  smPgno *aGobble;
28c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
28d0: 2a 20 47 6f 62 62 6c 65 20 70 6f 69 6e 74 20 66  * Gobble point f
28e0: 6f 72 20 65 61 63 68 20 69 6e 70 75 74 20 73 65  or each input se
28f0: 67 6d 65 6e 74 20 2a 2f 0a 0a 20 20 4c 73 6d 50  gment */..  LsmP
2900: 67 6e 6f 20 69 49 6e 64 69 72 65 63 74 3b 0a 20  gno iIndirect;. 
2910: 20 73 74 72 75 63 74 20 53 61 76 65 64 50 67 6e   struct SavedPgn
2920: 6f 20 7b 0a 20 20 20 20 4c 73 6d 50 67 6e 6f 20  o {.    LsmPgno 
2930: 69 50 67 6e 6f 3b 0a 20 20 20 20 69 6e 74 20 62  iPgno;.    int b
2940: 53 74 6f 72 65 3b 0a 20 20 7d 20 61 53 61 76 65  Store;.  } aSave
2950: 5b 32 5d 3b 0a 7d 3b 0a 0a 23 69 66 64 65 66 20  [2];.};..#ifdef 
2960: 4c 53 4d 5f 44 45 42 55 47 5f 45 58 50 45 4e 53  LSM_DEBUG_EXPENS
2970: 49 56 45 0a 73 74 61 74 69 63 20 69 6e 74 20 61  IVE.static int a
2980: 73 73 65 72 74 50 6f 69 6e 74 65 72 73 4f 6b 28  ssertPointersOk(
2990: 6c 73 6d 5f 64 62 20 2a 2c 20 53 65 67 6d 65 6e  lsm_db *, Segmen
29a0: 74 20 2a 2c 20 53 65 67 6d 65 6e 74 20 2a 2c 20  t *, Segment *, 
29b0: 69 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  int);.static int
29c0: 20 61 73 73 65 72 74 42 74 72 65 65 4f 6b 28 6c   assertBtreeOk(l
29d0: 73 6d 5f 64 62 20 2a 2c 20 53 65 67 6d 65 6e 74  sm_db *, Segment
29e0: 20 2a 29 3b 0a 73 74 61 74 69 63 20 76 6f 69 64   *);.static void
29f0: 20 61 73 73 65 72 74 52 75 6e 49 6e 4f 72 64 65   assertRunInOrde
2a00: 72 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 53  r(lsm_db *pDb, S
2a10: 65 67 6d 65 6e 74 20 2a 70 53 65 67 29 3b 0a 23  egment *pSeg);.#
2a20: 65 6c 73 65 0a 23 64 65 66 69 6e 65 20 61 73 73  else.#define ass
2a30: 65 72 74 52 75 6e 49 6e 4f 72 64 65 72 28 78 2c  ertRunInOrder(x,
2a40: 79 29 0a 23 64 65 66 69 6e 65 20 61 73 73 65 72  y).#define asser
2a50: 74 42 74 72 65 65 4f 6b 28 78 2c 79 29 0a 23 65  tBtreeOk(x,y).#e
2a60: 6e 64 69 66 0a 0a 0a 73 74 72 75 63 74 20 46 69  ndif...struct Fi
2a70: 6c 65 50 61 67 65 20 7b 20 75 38 20 2a 61 44 61  lePage { u8 *aDa
2a80: 74 61 3b 20 69 6e 74 20 6e 44 61 74 61 3b 20 7d  ta; int nData; }
2a90: 3b 0a 73 74 61 74 69 63 20 75 38 20 2a 66 73 50  ;.static u8 *fsP
2aa0: 61 67 65 44 61 74 61 28 50 61 67 65 20 2a 70 50  ageData(Page *pP
2ab0: 67 2c 20 69 6e 74 20 2a 70 6e 44 61 74 61 29 7b  g, int *pnData){
2ac0: 0a 20 20 2a 70 6e 44 61 74 61 20 3d 20 28 28 73  .  *pnData = ((s
2ad0: 74 72 75 63 74 20 46 69 6c 65 50 61 67 65 20 2a  truct FilePage *
2ae0: 29 28 70 50 67 29 29 2d 3e 6e 44 61 74 61 3b 0a  )(pPg))->nData;.
2af0: 20 20 72 65 74 75 72 6e 20 28 28 73 74 72 75 63    return ((struc
2b00: 74 20 46 69 6c 65 50 61 67 65 20 2a 29 28 70 50  t FilePage *)(pP
2b10: 67 29 29 2d 3e 61 44 61 74 61 3b 0a 7d 0a 2f 2a  g))->aData;.}./*
2b20: 55 4e 55 53 45 44 20 73 74 61 74 69 63 20 75 38  UNUSED static u8
2b30: 20 2a 66 73 50 61 67 65 44 61 74 61 50 74 72 28   *fsPageDataPtr(
2b40: 50 61 67 65 20 2a 70 50 67 29 7b 0a 20 20 72 65  Page *pPg){.  re
2b50: 74 75 72 6e 20 28 28 73 74 72 75 63 74 20 46 69  turn ((struct Fi
2b60: 6c 65 50 61 67 65 20 2a 29 28 70 50 67 29 29 2d  lePage *)(pPg))-
2b70: 3e 61 44 61 74 61 3b 0a 7d 2a 2f 0a 0a 2f 2a 0a  >aData;.}*/../*.
2b80: 2a 2a 20 57 72 69 74 65 20 6e 56 61 6c 20 61 73  ** Write nVal as
2b90: 20 61 20 31 36 2d 62 69 74 20 75 6e 73 69 67 6e   a 16-bit unsign
2ba0: 65 64 20 62 69 67 2d 65 6e 64 69 61 6e 20 69 6e  ed big-endian in
2bb0: 74 65 67 65 72 20 69 6e 74 6f 20 62 75 66 66 65  teger into buffe
2bc0: 72 20 61 4f 75 74 2e 0a 2a 2f 0a 76 6f 69 64 20  r aOut..*/.void 
2bd0: 6c 73 6d 50 75 74 55 31 36 28 75 38 20 2a 61 4f  lsmPutU16(u8 *aO
2be0: 75 74 2c 20 75 31 36 20 6e 56 61 6c 29 7b 0a 20  ut, u16 nVal){. 
2bf0: 20 61 4f 75 74 5b 30 5d 20 3d 20 28 75 38 29 28   aOut[0] = (u8)(
2c00: 28 6e 56 61 6c 3e 3e 38 29 20 26 20 30 78 46 46  (nVal>>8) & 0xFF
2c10: 29 3b 0a 20 20 61 4f 75 74 5b 31 5d 20 3d 20 28  );.  aOut[1] = (
2c20: 75 38 29 28 6e 56 61 6c 20 26 20 30 78 46 46 29  u8)(nVal & 0xFF)
2c30: 3b 0a 7d 0a 0a 76 6f 69 64 20 6c 73 6d 50 75 74  ;.}..void lsmPut
2c40: 55 33 32 28 75 38 20 2a 61 4f 75 74 2c 20 75 33  U32(u8 *aOut, u3
2c50: 32 20 6e 56 61 6c 29 7b 0a 20 20 61 4f 75 74 5b  2 nVal){.  aOut[
2c60: 30 5d 20 3d 20 28 75 38 29 28 28 6e 56 61 6c 3e  0] = (u8)((nVal>
2c70: 3e 32 34 29 20 26 20 30 78 46 46 29 3b 0a 20 20  >24) & 0xFF);.  
2c80: 61 4f 75 74 5b 31 5d 20 3d 20 28 75 38 29 28 28  aOut[1] = (u8)((
2c90: 6e 56 61 6c 3e 3e 31 36 29 20 26 20 30 78 46 46  nVal>>16) & 0xFF
2ca0: 29 3b 0a 20 20 61 4f 75 74 5b 32 5d 20 3d 20 28  );.  aOut[2] = (
2cb0: 75 38 29 28 28 6e 56 61 6c 3e 3e 20 38 29 20 26  u8)((nVal>> 8) &
2cc0: 20 30 78 46 46 29 3b 0a 20 20 61 4f 75 74 5b 33   0xFF);.  aOut[3
2cd0: 5d 20 3d 20 28 75 38 29 28 28 6e 56 61 6c 20 20  ] = (u8)((nVal  
2ce0: 20 20 29 20 26 20 30 78 46 46 29 3b 0a 7d 0a 0a    ) & 0xFF);.}..
2cf0: 69 6e 74 20 6c 73 6d 47 65 74 55 31 36 28 75 38  int lsmGetU16(u8
2d00: 20 2a 61 4f 75 74 29 7b 0a 20 20 72 65 74 75 72   *aOut){.  retur
2d10: 6e 20 28 61 4f 75 74 5b 30 5d 20 3c 3c 20 38 29  n (aOut[0] << 8)
2d20: 20 2b 20 61 4f 75 74 5b 31 5d 3b 0a 7d 0a 0a 75   + aOut[1];.}..u
2d30: 33 32 20 6c 73 6d 47 65 74 55 33 32 28 75 38 20  32 lsmGetU32(u8 
2d40: 2a 61 4f 75 74 29 7b 0a 20 20 72 65 74 75 72 6e  *aOut){.  return
2d50: 20 28 28 75 33 32 29 61 4f 75 74 5b 30 5d 20 3c   ((u32)aOut[0] <
2d60: 3c 20 32 34 29 20 0a 20 20 20 20 20 20 20 2b 20  < 24) .       + 
2d70: 28 28 75 33 32 29 61 4f 75 74 5b 31 5d 20 3c 3c  ((u32)aOut[1] <<
2d80: 20 31 36 29 20 0a 20 20 20 20 20 20 20 2b 20 28   16) .       + (
2d90: 28 75 33 32 29 61 4f 75 74 5b 32 5d 20 3c 3c 20  (u32)aOut[2] << 
2da0: 38 29 20 0a 20 20 20 20 20 20 20 2b 20 28 28 75  8) .       + ((u
2db0: 33 32 29 61 4f 75 74 5b 33 5d 29 3b 0a 7d 0a 0a  32)aOut[3]);.}..
2dc0: 75 36 34 20 6c 73 6d 47 65 74 55 36 34 28 75 38  u64 lsmGetU64(u8
2dd0: 20 2a 61 4f 75 74 29 7b 0a 20 20 72 65 74 75 72   *aOut){.  retur
2de0: 6e 20 28 28 75 36 34 29 61 4f 75 74 5b 30 5d 20  n ((u64)aOut[0] 
2df0: 3c 3c 20 35 36 29 20 0a 20 20 20 20 20 20 20 2b  << 56) .       +
2e00: 20 28 28 75 36 34 29 61 4f 75 74 5b 31 5d 20 3c   ((u64)aOut[1] <
2e10: 3c 20 34 38 29 20 0a 20 20 20 20 20 20 20 2b 20  < 48) .       + 
2e20: 28 28 75 36 34 29 61 4f 75 74 5b 32 5d 20 3c 3c  ((u64)aOut[2] <<
2e30: 20 34 30 29 20 0a 20 20 20 20 20 20 20 2b 20 28   40) .       + (
2e40: 28 75 36 34 29 61 4f 75 74 5b 33 5d 20 3c 3c 20  (u64)aOut[3] << 
2e50: 33 32 29 20 0a 20 20 20 20 20 20 20 2b 20 28 28  32) .       + ((
2e60: 75 36 34 29 61 4f 75 74 5b 34 5d 20 3c 3c 20 32  u64)aOut[4] << 2
2e70: 34 29 0a 20 20 20 20 20 20 20 2b 20 28 28 75 33  4).       + ((u3
2e80: 32 29 61 4f 75 74 5b 35 5d 20 3c 3c 20 31 36 29  2)aOut[5] << 16)
2e90: 20 0a 20 20 20 20 20 20 20 2b 20 28 28 75 33 32   .       + ((u32
2ea0: 29 61 4f 75 74 5b 36 5d 20 3c 3c 20 38 29 20 0a  )aOut[6] << 8) .
2eb0: 20 20 20 20 20 20 20 2b 20 28 28 75 33 32 29 61         + ((u32)a
2ec0: 4f 75 74 5b 37 5d 29 3b 0a 7d 0a 0a 76 6f 69 64  Out[7]);.}..void
2ed0: 20 6c 73 6d 50 75 74 55 36 34 28 75 38 20 2a 61   lsmPutU64(u8 *a
2ee0: 4f 75 74 2c 20 75 36 34 20 6e 56 61 6c 29 7b 0a  Out, u64 nVal){.
2ef0: 20 20 61 4f 75 74 5b 30 5d 20 3d 20 28 75 38 29    aOut[0] = (u8)
2f00: 28 28 6e 56 61 6c 3e 3e 35 36 29 20 26 20 30 78  ((nVal>>56) & 0x
2f10: 46 46 29 3b 0a 20 20 61 4f 75 74 5b 31 5d 20 3d  FF);.  aOut[1] =
2f20: 20 28 75 38 29 28 28 6e 56 61 6c 3e 3e 34 38 29   (u8)((nVal>>48)
2f30: 20 26 20 30 78 46 46 29 3b 0a 20 20 61 4f 75 74   & 0xFF);.  aOut
2f40: 5b 32 5d 20 3d 20 28 75 38 29 28 28 6e 56 61 6c  [2] = (u8)((nVal
2f50: 3e 3e 34 30 29 20 26 20 30 78 46 46 29 3b 0a 20  >>40) & 0xFF);. 
2f60: 20 61 4f 75 74 5b 33 5d 20 3d 20 28 75 38 29 28   aOut[3] = (u8)(
2f70: 28 6e 56 61 6c 3e 3e 33 32 29 20 26 20 30 78 46  (nVal>>32) & 0xF
2f80: 46 29 3b 0a 20 20 61 4f 75 74 5b 34 5d 20 3d 20  F);.  aOut[4] = 
2f90: 28 75 38 29 28 28 6e 56 61 6c 3e 3e 32 34 29 20  (u8)((nVal>>24) 
2fa0: 26 20 30 78 46 46 29 3b 0a 20 20 61 4f 75 74 5b  & 0xFF);.  aOut[
2fb0: 35 5d 20 3d 20 28 75 38 29 28 28 6e 56 61 6c 3e  5] = (u8)((nVal>
2fc0: 3e 31 36 29 20 26 20 30 78 46 46 29 3b 0a 20 20  >16) & 0xFF);.  
2fd0: 61 4f 75 74 5b 36 5d 20 3d 20 28 75 38 29 28 28  aOut[6] = (u8)((
2fe0: 6e 56 61 6c 3e 3e 20 38 29 20 26 20 30 78 46 46  nVal>> 8) & 0xFF
2ff0: 29 3b 0a 20 20 61 4f 75 74 5b 37 5d 20 3d 20 28  );.  aOut[7] = (
3000: 75 38 29 28 28 6e 56 61 6c 20 20 20 20 29 20 26  u8)((nVal    ) &
3010: 20 30 78 46 46 29 3b 0a 7d 0a 0a 73 74 61 74 69   0xFF);.}..stati
3020: 63 20 69 6e 74 20 73 6f 72 74 65 64 42 6c 6f 62  c int sortedBlob
3030: 47 72 6f 77 28 6c 73 6d 5f 65 6e 76 20 2a 70 45  Grow(lsm_env *pE
3040: 6e 76 2c 20 4c 73 6d 42 6c 6f 62 20 2a 70 42 6c  nv, LsmBlob *pBl
3050: 6f 62 2c 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a  ob, int nData){.
3060: 20 20 61 73 73 65 72 74 28 20 70 42 6c 6f 62 2d    assert( pBlob-
3070: 3e 70 45 6e 76 3d 3d 70 45 6e 76 20 7c 7c 20 28  >pEnv==pEnv || (
3080: 70 42 6c 6f 62 2d 3e 70 45 6e 76 3d 3d 30 20 26  pBlob->pEnv==0 &
3090: 26 20 70 42 6c 6f 62 2d 3e 70 44 61 74 61 3d 3d  & pBlob->pData==
30a0: 30 29 20 29 3b 0a 20 20 69 66 28 20 70 42 6c 6f  0) );.  if( pBlo
30b0: 62 2d 3e 6e 41 6c 6c 6f 63 3c 6e 44 61 74 61 20  b->nAlloc<nData 
30c0: 29 7b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 70 44  ){.    pBlob->pD
30d0: 61 74 61 20 3d 20 6c 73 6d 52 65 61 6c 6c 6f 63  ata = lsmRealloc
30e0: 4f 72 46 72 65 65 28 70 45 6e 76 2c 20 70 42 6c  OrFree(pEnv, pBl
30f0: 6f 62 2d 3e 70 44 61 74 61 2c 20 6e 44 61 74 61  ob->pData, nData
3100: 29 3b 0a 20 20 20 20 69 66 28 20 21 70 42 6c 6f  );.    if( !pBlo
3110: 62 2d 3e 70 44 61 74 61 20 29 20 72 65 74 75 72  b->pData ) retur
3120: 6e 20 4c 53 4d 5f 4e 4f 4d 45 4d 5f 42 4b 50 54  n LSM_NOMEM_BKPT
3130: 3b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 6e 41 6c  ;.    pBlob->nAl
3140: 6c 6f 63 20 3d 20 6e 44 61 74 61 3b 0a 20 20 20  loc = nData;.   
3150: 20 70 42 6c 6f 62 2d 3e 70 45 6e 76 20 3d 20 70   pBlob->pEnv = p
3160: 45 6e 76 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  Env;.  }.  retur
3170: 6e 20 4c 53 4d 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61  n LSM_OK;.}..sta
3180: 74 69 63 20 69 6e 74 20 73 6f 72 74 65 64 42 6c  tic int sortedBl
3190: 6f 62 53 65 74 28 6c 73 6d 5f 65 6e 76 20 2a 70  obSet(lsm_env *p
31a0: 45 6e 76 2c 20 4c 73 6d 42 6c 6f 62 20 2a 70 42  Env, LsmBlob *pB
31b0: 6c 6f 62 2c 20 76 6f 69 64 20 2a 70 44 61 74 61  lob, void *pData
31c0: 2c 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20  , int nData){.  
31d0: 69 66 28 20 73 6f 72 74 65 64 42 6c 6f 62 47 72  if( sortedBlobGr
31e0: 6f 77 28 70 45 6e 76 2c 20 70 42 6c 6f 62 2c 20  ow(pEnv, pBlob, 
31f0: 6e 44 61 74 61 29 20 29 20 72 65 74 75 72 6e 20  nData) ) return 
3200: 4c 53 4d 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65 6d  LSM_NOMEM;.  mem
3210: 63 70 79 28 70 42 6c 6f 62 2d 3e 70 44 61 74 61  cpy(pBlob->pData
3220: 2c 20 70 44 61 74 61 2c 20 6e 44 61 74 61 29 3b  , pData, nData);
3230: 0a 20 20 70 42 6c 6f 62 2d 3e 6e 44 61 74 61 20  .  pBlob->nData 
3240: 3d 20 6e 44 61 74 61 3b 0a 20 20 72 65 74 75 72  = nData;.  retur
3250: 6e 20 4c 53 4d 5f 4f 4b 3b 0a 7d 0a 0a 23 69 66  n LSM_OK;.}..#if
3260: 20 30 0a 73 74 61 74 69 63 20 69 6e 74 20 73 6f   0.static int so
3270: 72 74 65 64 42 6c 6f 62 43 6f 70 79 28 4c 73 6d  rtedBlobCopy(Lsm
3280: 42 6c 6f 62 20 2a 70 44 65 73 74 2c 20 4c 73 6d  Blob *pDest, Lsm
3290: 42 6c 6f 62 20 2a 70 53 72 63 29 7b 0a 20 20 72  Blob *pSrc){.  r
32a0: 65 74 75 72 6e 20 73 6f 72 74 65 64 42 6c 6f 62  eturn sortedBlob
32b0: 53 65 74 28 70 44 65 73 74 2c 20 70 53 72 63 2d  Set(pDest, pSrc-
32c0: 3e 70 44 61 74 61 2c 20 70 53 72 63 2d 3e 6e 44  >pData, pSrc->nD
32d0: 61 74 61 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a  ata);.}.#endif..
32e0: 73 74 61 74 69 63 20 76 6f 69 64 20 73 6f 72 74  static void sort
32f0: 65 64 42 6c 6f 62 46 72 65 65 28 4c 73 6d 42 6c  edBlobFree(LsmBl
3300: 6f 62 20 2a 70 42 6c 6f 62 29 7b 0a 20 20 61 73  ob *pBlob){.  as
3310: 73 65 72 74 28 20 70 42 6c 6f 62 2d 3e 70 45 6e  sert( pBlob->pEn
3320: 76 20 7c 7c 20 70 42 6c 6f 62 2d 3e 70 44 61 74  v || pBlob->pDat
3330: 61 3d 3d 30 20 29 3b 0a 20 20 69 66 28 20 70 42  a==0 );.  if( pB
3340: 6c 6f 62 2d 3e 70 44 61 74 61 20 29 20 6c 73 6d  lob->pData ) lsm
3350: 46 72 65 65 28 70 42 6c 6f 62 2d 3e 70 45 6e 76  Free(pBlob->pEnv
3360: 2c 20 70 42 6c 6f 62 2d 3e 70 44 61 74 61 29 3b  , pBlob->pData);
3370: 0a 20 20 6d 65 6d 73 65 74 28 70 42 6c 6f 62 2c  .  memset(pBlob,
3380: 20 30 2c 20 73 69 7a 65 6f 66 28 4c 73 6d 42 6c   0, sizeof(LsmBl
3390: 6f 62 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  ob));.}..static 
33a0: 69 6e 74 20 73 6f 72 74 65 64 52 65 61 64 44 61  int sortedReadDa
33b0: 74 61 28 0a 20 20 53 65 67 6d 65 6e 74 20 2a 70  ta(.  Segment *p
33c0: 53 65 67 2c 0a 20 20 50 61 67 65 20 2a 70 50 67  Seg,.  Page *pPg
33d0: 2c 0a 20 20 69 6e 74 20 69 4f 66 66 2c 0a 20 20  ,.  int iOff,.  
33e0: 69 6e 74 20 6e 42 79 74 65 2c 0a 20 20 76 6f 69  int nByte,.  voi
33f0: 64 20 2a 2a 70 70 44 61 74 61 2c 0a 20 20 4c 73  d **ppData,.  Ls
3400: 6d 42 6c 6f 62 20 2a 70 42 6c 6f 62 0a 29 7b 0a  mBlob *pBlob.){.
3410: 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f    int rc = LSM_O
3420: 4b 3b 0a 20 20 69 6e 74 20 69 45 6e 64 3b 0a 20  K;.  int iEnd;. 
3430: 20 69 6e 74 20 6e 44 61 74 61 3b 0a 20 20 69 6e   int nData;.  in
3440: 74 20 6e 43 65 6c 6c 3b 0a 20 20 75 38 20 2a 61  t nCell;.  u8 *a
3450: 44 61 74 61 3b 0a 0a 20 20 61 44 61 74 61 20 3d  Data;..  aData =
3460: 20 66 73 50 61 67 65 44 61 74 61 28 70 50 67 2c   fsPageData(pPg,
3470: 20 26 6e 44 61 74 61 29 3b 0a 20 20 6e 43 65 6c   &nData);.  nCel
3480: 6c 20 3d 20 6c 73 6d 47 65 74 55 31 36 28 26 61  l = lsmGetU16(&a
3490: 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f 4e 52 45  Data[SEGMENT_NRE
34a0: 43 4f 52 44 5f 4f 46 46 53 45 54 28 6e 44 61 74  CORD_OFFSET(nDat
34b0: 61 29 5d 29 3b 0a 20 20 69 45 6e 64 20 3d 20 53  a)]);.  iEnd = S
34c0: 45 47 4d 45 4e 54 5f 45 4f 46 28 6e 44 61 74 61  EGMENT_EOF(nData
34d0: 2c 20 6e 43 65 6c 6c 29 3b 0a 20 20 61 73 73 65  , nCell);.  asse
34e0: 72 74 28 20 69 45 6e 64 3e 30 20 26 26 20 69 45  rt( iEnd>0 && iE
34f0: 6e 64 3c 6e 44 61 74 61 20 29 3b 0a 0a 20 20 69  nd<nData );..  i
3500: 66 28 20 69 4f 66 66 2b 6e 42 79 74 65 3c 3d 69  f( iOff+nByte<=i
3510: 45 6e 64 20 29 7b 0a 20 20 20 20 2a 70 70 44 61  End ){.    *ppDa
3520: 74 61 20 3d 20 28 76 6f 69 64 20 2a 29 26 61 44  ta = (void *)&aD
3530: 61 74 61 5b 69 4f 66 66 5d 3b 0a 20 20 7d 65 6c  ata[iOff];.  }el
3540: 73 65 7b 0a 20 20 20 20 69 6e 74 20 6e 52 65 6d  se{.    int nRem
3550: 20 3d 20 6e 42 79 74 65 3b 0a 20 20 20 20 69 6e   = nByte;.    in
3560: 74 20 69 20 3d 20 69 4f 66 66 3b 0a 20 20 20 20  t i = iOff;.    
3570: 75 38 20 2a 61 44 65 73 74 3b 0a 0a 20 20 20 20  u8 *aDest;..    
3580: 2f 2a 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65  /* Make sure the
3590: 20 62 6c 6f 62 20 69 73 20 62 69 67 20 65 6e 6f   blob is big eno
35a0: 75 67 68 20 74 6f 20 73 74 6f 72 65 20 74 68 65  ugh to store the
35b0: 20 76 61 6c 75 65 20 62 65 69 6e 67 20 6c 6f 61   value being loa
35c0: 64 65 64 2e 20 2a 2f 0a 20 20 20 20 72 63 20 3d  ded. */.    rc =
35d0: 20 73 6f 72 74 65 64 42 6c 6f 62 47 72 6f 77 28   sortedBlobGrow(
35e0: 6c 73 6d 50 61 67 65 45 6e 76 28 70 50 67 29 2c  lsmPageEnv(pPg),
35f0: 20 70 42 6c 6f 62 2c 20 6e 42 79 74 65 29 3b 0a   pBlob, nByte);.
3600: 20 20 20 20 69 66 28 20 72 63 21 3d 4c 53 4d 5f      if( rc!=LSM_
3610: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
3620: 20 20 20 20 70 42 6c 6f 62 2d 3e 6e 44 61 74 61      pBlob->nData
3630: 20 3d 20 6e 42 79 74 65 3b 0a 20 20 20 20 61 44   = nByte;.    aD
3640: 65 73 74 20 3d 20 28 75 38 20 2a 29 70 42 6c 6f  est = (u8 *)pBlo
3650: 62 2d 3e 70 44 61 74 61 3b 0a 20 20 20 20 2a 70  b->pData;.    *p
3660: 70 44 61 74 61 20 3d 20 70 42 6c 6f 62 2d 3e 70  pData = pBlob->p
3670: 44 61 74 61 3b 0a 0a 20 20 20 20 2f 2a 20 49 6e  Data;..    /* In
3680: 63 72 65 6d 65 6e 74 20 74 68 65 20 70 6f 69 6e  crement the poin
3690: 74 65 72 20 70 61 67 65 73 20 72 65 66 2d 63 6f  ter pages ref-co
36a0: 75 6e 74 2e 20 2a 2f 0a 20 20 20 20 6c 73 6d 46  unt. */.    lsmF
36b0: 73 50 61 67 65 52 65 66 28 70 50 67 29 3b 0a 0a  sPageRef(pPg);..
36c0: 20 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 4c      while( rc==L
36d0: 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 50  SM_OK ){.      P
36e0: 61 67 65 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20  age *pNext;.    
36f0: 20 20 69 6e 74 20 66 6c 61 67 73 3b 0a 0a 20 20    int flags;..  
3700: 20 20 20 20 2f 2a 20 43 6f 70 79 20 64 61 74 61      /* Copy data
3710: 20 66 72 6f 6d 20 70 50 67 20 69 6e 74 6f 20 74   from pPg into t
3720: 68 65 20 6f 75 74 70 75 74 20 62 75 66 66 65 72  he output buffer
3730: 2e 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e  . */.      int n
3740: 43 6f 70 79 20 3d 20 4c 53 4d 5f 4d 49 4e 28 6e  Copy = LSM_MIN(n
3750: 52 65 6d 2c 20 69 45 6e 64 2d 69 29 3b 0a 20 20  Rem, iEnd-i);.  
3760: 20 20 20 20 69 66 28 20 6e 43 6f 70 79 3e 30 20      if( nCopy>0 
3770: 29 7b 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 70  ){.        memcp
3780: 79 28 26 61 44 65 73 74 5b 6e 42 79 74 65 2d 6e  y(&aDest[nByte-n
3790: 52 65 6d 5d 2c 20 26 61 44 61 74 61 5b 69 5d 2c  Rem], &aData[i],
37a0: 20 6e 43 6f 70 79 29 3b 0a 20 20 20 20 20 20 20   nCopy);.       
37b0: 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b 0a   nRem -= nCopy;.
37c0: 20 20 20 20 20 20 20 20 69 20 2b 3d 20 6e 43 6f          i += nCo
37d0: 70 79 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65  py;.        asse
37e0: 72 74 28 20 6e 52 65 6d 3d 3d 30 20 7c 7c 20 69  rt( nRem==0 || i
37f0: 3d 3d 69 45 6e 64 20 29 3b 0a 20 20 20 20 20 20  ==iEnd );.      
3800: 7d 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  }.      assert( 
3810: 6e 52 65 6d 3e 3d 30 20 29 3b 0a 20 20 20 20 20  nRem>=0 );.     
3820: 20 69 66 28 20 6e 52 65 6d 3d 3d 30 20 29 20 62   if( nRem==0 ) b
3830: 72 65 61 6b 3b 0a 20 20 20 20 20 20 69 20 2d 3d  reak;.      i -=
3840: 20 69 45 6e 64 3b 0a 0a 20 20 20 20 20 20 2f 2a   iEnd;..      /*
3850: 20 47 72 61 62 20 74 68 65 20 6e 65 78 74 20 70   Grab the next p
3860: 61 67 65 20 69 6e 20 74 68 65 20 73 65 67 6d 65  age in the segme
3870: 6e 74 20 2a 2f 0a 0a 20 20 20 20 20 20 64 6f 20  nt */..      do 
3880: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 6c  {.        rc = l
3890: 73 6d 46 73 44 62 50 61 67 65 4e 65 78 74 28 70  smFsDbPageNext(p
38a0: 53 65 67 2c 20 70 50 67 2c 20 31 2c 20 26 70 4e  Seg, pPg, 1, &pN
38b0: 65 78 74 29 3b 0a 20 20 20 20 20 20 20 20 69 66  ext);.        if
38c0: 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20  ( rc==LSM_OK && 
38d0: 70 4e 65 78 74 3d 3d 30 20 29 7b 0a 20 20 20 20  pNext==0 ){.    
38e0: 20 20 20 20 20 20 72 63 20 3d 20 4c 53 4d 5f 43        rc = LSM_C
38f0: 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20  ORRUPT_BKPT;.   
3900: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69       }.        i
3910: 66 28 20 72 63 20 29 20 62 72 65 61 6b 3b 0a 20  f( rc ) break;. 
3920: 20 20 20 20 20 20 20 6c 73 6d 46 73 50 61 67 65         lsmFsPage
3930: 52 65 6c 65 61 73 65 28 70 50 67 29 3b 0a 20 20  Release(pPg);.  
3940: 20 20 20 20 20 20 70 50 67 20 3d 20 70 4e 65 78        pPg = pNex
3950: 74 3b 0a 20 20 20 20 20 20 20 20 61 44 61 74 61  t;.        aData
3960: 20 3d 20 66 73 50 61 67 65 44 61 74 61 28 70 50   = fsPageData(pP
3970: 67 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20 20 20  g, &nData);.    
3980: 20 20 20 20 66 6c 61 67 73 20 3d 20 6c 73 6d 47      flags = lsmG
3990: 65 74 55 31 36 28 26 61 44 61 74 61 5b 53 45 47  etU16(&aData[SEG
39a0: 4d 45 4e 54 5f 46 4c 41 47 53 5f 4f 46 46 53 45  MENT_FLAGS_OFFSE
39b0: 54 28 6e 44 61 74 61 29 5d 29 3b 0a 20 20 20 20  T(nData)]);.    
39c0: 20 20 7d 77 68 69 6c 65 28 20 66 6c 61 67 73 26    }while( flags&
39d0: 53 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c  SEGMENT_BTREE_FL
39e0: 41 47 20 29 3b 0a 0a 20 20 20 20 20 20 69 45 6e  AG );..      iEn
39f0: 64 20 3d 20 53 45 47 4d 45 4e 54 5f 45 4f 46 28  d = SEGMENT_EOF(
3a00: 6e 44 61 74 61 2c 20 6c 73 6d 47 65 74 55 31 36  nData, lsmGetU16
3a10: 28 26 61 44 61 74 61 5b 6e 44 61 74 61 2d 32 5d  (&aData[nData-2]
3a20: 29 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  ));.      assert
3a30: 28 20 69 45 6e 64 3e 30 20 26 26 20 69 45 6e 64  ( iEnd>0 && iEnd
3a40: 3c 6e 44 61 74 61 20 29 3b 0a 20 20 20 20 7d 0a  <nData );.    }.
3a50: 0a 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65  .    lsmFsPageRe
3a60: 6c 65 61 73 65 28 70 50 67 29 3b 0a 20 20 7d 0a  lease(pPg);.  }.
3a70: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
3a80: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 61 67 65  .static int page
3a90: 47 65 74 4e 52 65 63 28 75 38 20 2a 61 44 61 74  GetNRec(u8 *aDat
3aa0: 61 2c 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20  a, int nData){. 
3ab0: 20 72 65 74 75 72 6e 20 28 69 6e 74 29 6c 73 6d   return (int)lsm
3ac0: 47 65 74 55 31 36 28 26 61 44 61 74 61 5b 53 45  GetU16(&aData[SE
3ad0: 47 4d 45 4e 54 5f 4e 52 45 43 4f 52 44 5f 4f 46  GMENT_NRECORD_OF
3ae0: 46 53 45 54 28 6e 44 61 74 61 29 5d 29 3b 0a 7d  FSET(nData)]);.}
3af0: 0a 0a 73 74 61 74 69 63 20 4c 73 6d 50 67 6e 6f  ..static LsmPgno
3b00: 20 70 61 67 65 47 65 74 50 74 72 28 75 38 20 2a   pageGetPtr(u8 *
3b10: 61 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61  aData, int nData
3b20: 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 4c 73 6d  ){.  return (Lsm
3b30: 50 67 6e 6f 29 6c 73 6d 47 65 74 55 36 34 28 26  Pgno)lsmGetU64(&
3b40: 61 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f 50 4f  aData[SEGMENT_PO
3b50: 49 4e 54 45 52 5f 4f 46 46 53 45 54 28 6e 44 61  INTER_OFFSET(nDa
3b60: 74 61 29 5d 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  ta)]);.}..static
3b70: 20 69 6e 74 20 70 61 67 65 47 65 74 46 6c 61 67   int pageGetFlag
3b80: 73 28 75 38 20 2a 61 44 61 74 61 2c 20 69 6e 74  s(u8 *aData, int
3b90: 20 6e 44 61 74 61 29 7b 0a 20 20 72 65 74 75 72   nData){.  retur
3ba0: 6e 20 28 69 6e 74 29 6c 73 6d 47 65 74 55 31 36  n (int)lsmGetU16
3bb0: 28 26 61 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f  (&aData[SEGMENT_
3bc0: 46 4c 41 47 53 5f 4f 46 46 53 45 54 28 6e 44 61  FLAGS_OFFSET(nDa
3bd0: 74 61 29 5d 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  ta)]);.}..static
3be0: 20 75 38 20 2a 70 61 67 65 47 65 74 43 65 6c 6c   u8 *pageGetCell
3bf0: 28 75 38 20 2a 61 44 61 74 61 2c 20 69 6e 74 20  (u8 *aData, int 
3c00: 6e 44 61 74 61 2c 20 69 6e 74 20 69 43 65 6c 6c  nData, int iCell
3c10: 29 7b 0a 20 20 72 65 74 75 72 6e 20 26 61 44 61  ){.  return &aDa
3c20: 74 61 5b 6c 73 6d 47 65 74 55 31 36 28 26 61 44  ta[lsmGetU16(&aD
3c30: 61 74 61 5b 53 45 47 4d 45 4e 54 5f 43 45 4c 4c  ata[SEGMENT_CELL
3c40: 50 54 52 5f 4f 46 46 53 45 54 28 6e 44 61 74 61  PTR_OFFSET(nData
3c50: 2c 20 69 43 65 6c 6c 29 5d 29 5d 3b 0a 7d 0a 0a  , iCell)])];.}..
3c60: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
3c70: 20 6e 75 6d 62 65 72 20 6f 66 20 63 65 6c 6c 73   number of cells
3c80: 20 6f 6e 20 70 61 67 65 20 70 50 67 2e 0a 2a 2f   on page pPg..*/
3c90: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 61 67 65  .static int page
3ca0: 4f 62 6a 47 65 74 4e 52 65 63 28 50 61 67 65 20  ObjGetNRec(Page 
3cb0: 2a 70 50 67 29 7b 0a 20 20 69 6e 74 20 6e 44 61  *pPg){.  int nDa
3cc0: 74 61 3b 0a 20 20 75 38 20 2a 61 44 61 74 61 20  ta;.  u8 *aData 
3cd0: 3d 20 6c 73 6d 46 73 50 61 67 65 44 61 74 61 28  = lsmFsPageData(
3ce0: 70 50 67 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20  pPg, &nData);.  
3cf0: 72 65 74 75 72 6e 20 70 61 67 65 47 65 74 4e 52  return pageGetNR
3d00: 65 63 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29  ec(aData, nData)
3d10: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
3d20: 6e 20 74 68 65 20 64 65 63 6f 64 65 64 20 28 70  n the decoded (p
3d30: 6f 73 73 69 62 6c 79 20 72 65 6c 61 74 69 76 65  ossibly relative
3d40: 29 20 70 6f 69 6e 74 65 72 20 76 61 6c 75 65 20  ) pointer value 
3d50: 73 74 6f 72 65 64 20 69 6e 20 63 65 6c 6c 20 0a  stored in cell .
3d60: 2a 2a 20 69 43 65 6c 6c 20 66 72 6f 6d 20 70 61  ** iCell from pa
3d70: 67 65 20 61 44 61 74 61 2f 6e 44 61 74 61 2e 0a  ge aData/nData..
3d80: 2a 2f 0a 73 74 61 74 69 63 20 4c 73 6d 50 67 6e  */.static LsmPgn
3d90: 6f 20 70 61 67 65 47 65 74 52 65 63 6f 72 64 50  o pageGetRecordP
3da0: 74 72 28 75 38 20 2a 61 44 61 74 61 2c 20 69 6e  tr(u8 *aData, in
3db0: 74 20 6e 44 61 74 61 2c 20 69 6e 74 20 69 43 65  t nData, int iCe
3dc0: 6c 6c 29 7b 0a 20 20 4c 73 6d 50 67 6e 6f 20 69  ll){.  LsmPgno i
3dd0: 52 65 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  Ret;            
3de0: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
3df0: 20 76 61 6c 75 65 20 2a 2f 0a 20 20 75 38 20 2a   value */.  u8 *
3e00: 61 43 65 6c 6c 3b 20 20 20 20 20 20 20 20 20 20  aCell;          
3e10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
3e20: 6f 69 6e 74 65 72 20 74 6f 20 63 65 6c 6c 20 69  ointer to cell i
3e30: 43 65 6c 6c 20 2a 2f 0a 0a 20 20 61 73 73 65 72  Cell */..  asser
3e40: 74 28 20 69 43 65 6c 6c 3c 70 61 67 65 47 65 74  t( iCell<pageGet
3e50: 4e 52 65 63 28 61 44 61 74 61 2c 20 6e 44 61 74  NRec(aData, nDat
3e60: 61 29 20 26 26 20 69 43 65 6c 6c 3e 3d 30 20 29  a) && iCell>=0 )
3e70: 3b 0a 20 20 61 43 65 6c 6c 20 3d 20 70 61 67 65  ;.  aCell = page
3e80: 47 65 74 43 65 6c 6c 28 61 44 61 74 61 2c 20 6e  GetCell(aData, n
3e90: 44 61 74 61 2c 20 69 43 65 6c 6c 29 3b 0a 20 20  Data, iCell);.  
3ea0: 6c 73 6d 56 61 72 69 6e 74 47 65 74 36 34 28 26  lsmVarintGet64(&
3eb0: 61 43 65 6c 6c 5b 31 5d 2c 20 26 69 52 65 74 29  aCell[1], &iRet)
3ec0: 3b 0a 20 20 72 65 74 75 72 6e 20 69 52 65 74 3b  ;.  return iRet;
3ed0: 0a 7d 0a 0a 73 74 61 74 69 63 20 75 38 20 2a 70  .}..static u8 *p
3ee0: 61 67 65 47 65 74 4b 65 79 28 0a 20 20 53 65 67  ageGetKey(.  Seg
3ef0: 6d 65 6e 74 20 2a 70 53 65 67 2c 20 20 20 20 20  ment *pSeg,     
3f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3f10: 53 65 67 6d 65 6e 74 20 70 50 67 20 62 65 6c 6f  Segment pPg belo
3f20: 6e 67 73 20 74 6f 20 2a 2f 0a 20 20 50 61 67 65  ngs to */.  Page
3f30: 20 2a 70 50 67 2c 20 20 20 20 20 20 20 20 20 20   *pPg,          
3f40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
3f50: 61 67 65 20 74 6f 20 72 65 61 64 20 66 72 6f 6d  age to read from
3f60: 20 2a 2f 0a 20 20 69 6e 74 20 69 43 65 6c 6c 2c   */.  int iCell,
3f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3f80: 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f        /* Index o
3f90: 66 20 63 65 6c 6c 20 6f 6e 20 70 61 67 65 20 74  f cell on page t
3fa0: 6f 20 72 65 61 64 20 2a 2f 0a 20 20 69 6e 74 20  o read */.  int 
3fb0: 2a 70 69 54 6f 70 69 63 2c 20 20 20 20 20 20 20  *piTopic,       
3fc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
3fd0: 55 54 3a 20 54 6f 70 69 63 20 61 73 73 6f 63 69  UT: Topic associ
3fe0: 61 74 65 64 20 77 69 74 68 20 74 68 69 73 20 6b  ated with this k
3ff0: 65 79 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4b  ey */.  int *pnK
4000: 65 79 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ey,             
4010: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
4020: 53 69 7a 65 20 6f 66 20 6b 65 79 20 69 6e 20 62  Size of key in b
4030: 79 74 65 73 20 2a 2f 0a 20 20 4c 73 6d 42 6c 6f  ytes */.  LsmBlo
4040: 62 20 2a 70 42 6c 6f 62 20 20 20 20 20 20 20 20  b *pBlob        
4050: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20            /* If 
4060: 72 65 71 75 69 72 65 64 2c 20 75 73 65 20 74 68  required, use th
4070: 69 73 20 66 6f 72 20 64 79 6e 61 6d 69 63 20 6d  is for dynamic m
4080: 65 6d 6f 72 79 20 2a 2f 0a 29 7b 0a 20 20 75 38  emory */.){.  u8
4090: 20 2a 70 4b 65 79 3b 0a 20 20 69 6e 74 20 6e 44   *pKey;.  int nD
40a0: 75 6d 6d 79 3b 0a 20 20 69 6e 74 20 65 54 79 70  ummy;.  int eTyp
40b0: 65 3b 0a 20 20 75 38 20 2a 61 44 61 74 61 3b 0a  e;.  u8 *aData;.
40c0: 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a 0a 20 20    int nData;..  
40d0: 61 44 61 74 61 20 3d 20 66 73 50 61 67 65 44 61  aData = fsPageDa
40e0: 74 61 28 70 50 67 2c 20 26 6e 44 61 74 61 29 3b  ta(pPg, &nData);
40f0: 0a 0a 20 20 61 73 73 65 72 74 28 20 21 28 70 61  ..  assert( !(pa
4100: 67 65 47 65 74 46 6c 61 67 73 28 61 44 61 74 61  geGetFlags(aData
4110: 2c 20 6e 44 61 74 61 29 20 26 20 53 45 47 4d 45  , nData) & SEGME
4120: 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 29 20 29  NT_BTREE_FLAG) )
4130: 3b 0a 20 20 61 73 73 65 72 74 28 20 69 43 65 6c  ;.  assert( iCel
4140: 6c 3c 70 61 67 65 47 65 74 4e 52 65 63 28 61 44  l<pageGetNRec(aD
4150: 61 74 61 2c 20 6e 44 61 74 61 29 20 29 3b 0a 0a  ata, nData) );..
4160: 20 20 70 4b 65 79 20 3d 20 70 61 67 65 47 65 74    pKey = pageGet
4170: 43 65 6c 6c 28 61 44 61 74 61 2c 20 6e 44 61 74  Cell(aData, nDat
4180: 61 2c 20 69 43 65 6c 6c 29 3b 0a 20 20 65 54 79  a, iCell);.  eTy
4190: 70 65 20 3d 20 2a 70 4b 65 79 2b 2b 3b 0a 20 20  pe = *pKey++;.  
41a0: 70 4b 65 79 20 2b 3d 20 6c 73 6d 56 61 72 69 6e  pKey += lsmVarin
41b0: 74 47 65 74 33 32 28 70 4b 65 79 2c 20 26 6e 44  tGet32(pKey, &nD
41c0: 75 6d 6d 79 29 3b 0a 20 20 70 4b 65 79 20 2b 3d  ummy);.  pKey +=
41d0: 20 6c 73 6d 56 61 72 69 6e 74 47 65 74 33 32 28   lsmVarintGet32(
41e0: 70 4b 65 79 2c 20 70 6e 4b 65 79 29 3b 0a 20 20  pKey, pnKey);.  
41f0: 69 66 28 20 72 74 49 73 57 72 69 74 65 28 65 54  if( rtIsWrite(eT
4200: 79 70 65 29 20 29 7b 0a 20 20 20 20 70 4b 65 79  ype) ){.    pKey
4210: 20 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 47 65 74   += lsmVarintGet
4220: 33 32 28 70 4b 65 79 2c 20 26 6e 44 75 6d 6d 79  32(pKey, &nDummy
4230: 29 3b 0a 20 20 7d 0a 20 20 2a 70 69 54 6f 70 69  );.  }.  *piTopi
4240: 63 20 3d 20 72 74 54 6f 70 69 63 28 65 54 79 70  c = rtTopic(eTyp
4250: 65 29 3b 0a 0a 20 20 73 6f 72 74 65 64 52 65 61  e);..  sortedRea
4260: 64 44 61 74 61 28 70 53 65 67 2c 20 70 50 67 2c  dData(pSeg, pPg,
4270: 20 70 4b 65 79 2d 61 44 61 74 61 2c 20 2a 70 6e   pKey-aData, *pn
4280: 4b 65 79 2c 20 28 76 6f 69 64 20 2a 2a 29 26 70  Key, (void **)&p
4290: 4b 65 79 2c 20 70 42 6c 6f 62 29 3b 0a 20 20 72  Key, pBlob);.  r
42a0: 65 74 75 72 6e 20 70 4b 65 79 3b 0a 7d 0a 0a 73  eturn pKey;.}..s
42b0: 74 61 74 69 63 20 69 6e 74 20 70 61 67 65 47 65  tatic int pageGe
42c0: 74 4b 65 79 43 6f 70 79 28 0a 20 20 6c 73 6d 5f  tKeyCopy(.  lsm_
42d0: 65 6e 76 20 2a 70 45 6e 76 2c 20 20 20 20 20 20  env *pEnv,      
42e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45              /* E
42f0: 6e 76 69 72 6f 6e 6d 65 6e 74 20 68 61 6e 64 6c  nvironment handl
4300: 65 20 2a 2f 0a 20 20 53 65 67 6d 65 6e 74 20 2a  e */.  Segment *
4310: 70 53 65 67 2c 20 20 20 20 20 20 20 20 20 20 20  pSeg,           
4320: 20 20 20 20 20 20 20 2f 2a 20 53 65 67 6d 65 6e         /* Segmen
4330: 74 20 70 50 67 20 62 65 6c 6f 6e 67 73 20 74 6f  t pPg belongs to
4340: 20 2a 2f 0a 20 20 50 61 67 65 20 2a 70 50 67 2c   */.  Page *pPg,
4350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4360: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 74 6f        /* Page to
4370: 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20   read from */.  
4380: 69 6e 74 20 69 43 65 6c 6c 2c 20 20 20 20 20 20  int iCell,      
4390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
43a0: 2f 2a 20 49 6e 64 65 78 20 6f 66 20 63 65 6c 6c  /* Index of cell
43b0: 20 6f 6e 20 70 61 67 65 20 74 6f 20 72 65 61 64   on page to read
43c0: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 69 54 6f 70   */.  int *piTop
43d0: 69 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ic,             
43e0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f        /* OUT: To
43f0: 70 69 63 20 61 73 73 6f 63 69 61 74 65 64 20 77  pic associated w
4400: 69 74 68 20 74 68 69 73 20 6b 65 79 20 2a 2f 0a  ith this key */.
4410: 20 20 4c 73 6d 42 6c 6f 62 20 2a 70 42 6c 6f 62    LsmBlob *pBlob
4420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4430: 20 20 2f 2a 20 49 66 20 72 65 71 75 69 72 65 64    /* If required
4440: 2c 20 75 73 65 20 74 68 69 73 20 66 6f 72 20 64  , use this for d
4450: 79 6e 61 6d 69 63 20 6d 65 6d 6f 72 79 20 2a 2f  ynamic memory */
4460: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c  .){.  int rc = L
4470: 53 4d 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 4b 65  SM_OK;.  int nKe
4480: 79 3b 0a 20 20 75 38 20 2a 61 4b 65 79 3b 0a 0a  y;.  u8 *aKey;..
4490: 20 20 61 4b 65 79 20 3d 20 70 61 67 65 47 65 74    aKey = pageGet
44a0: 4b 65 79 28 70 53 65 67 2c 20 70 50 67 2c 20 69  Key(pSeg, pPg, i
44b0: 43 65 6c 6c 2c 20 70 69 54 6f 70 69 63 2c 20 26  Cell, piTopic, &
44c0: 6e 4b 65 79 2c 20 70 42 6c 6f 62 29 3b 0a 20 20  nKey, pBlob);.  
44d0: 61 73 73 65 72 74 28 20 28 76 6f 69 64 20 2a 29  assert( (void *)
44e0: 61 4b 65 79 21 3d 70 42 6c 6f 62 2d 3e 70 44 61  aKey!=pBlob->pDa
44f0: 74 61 20 7c 7c 20 6e 4b 65 79 3d 3d 70 42 6c 6f  ta || nKey==pBlo
4500: 62 2d 3e 6e 44 61 74 61 20 29 3b 0a 20 20 69 66  b->nData );.  if
4510: 28 20 28 76 6f 69 64 20 2a 29 61 4b 65 79 21 3d  ( (void *)aKey!=
4520: 70 42 6c 6f 62 2d 3e 70 44 61 74 61 20 29 7b 0a  pBlob->pData ){.
4530: 20 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64 42      rc = sortedB
4540: 6c 6f 62 53 65 74 28 70 45 6e 76 2c 20 70 42 6c  lobSet(pEnv, pBl
4550: 6f 62 2c 20 61 4b 65 79 2c 20 6e 4b 65 79 29 3b  ob, aKey, nKey);
4560: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
4570: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 4c 73 6d  c;.}..static Lsm
4580: 50 67 6e 6f 20 70 61 67 65 47 65 74 42 74 72 65  Pgno pageGetBtre
4590: 65 52 65 66 28 50 61 67 65 20 2a 70 50 67 2c 20  eRef(Page *pPg, 
45a0: 69 6e 74 20 69 4b 65 79 29 7b 0a 20 20 4c 73 6d  int iKey){.  Lsm
45b0: 50 67 6e 6f 20 69 52 65 66 3b 0a 20 20 75 38 20  Pgno iRef;.  u8 
45c0: 2a 61 44 61 74 61 3b 0a 20 20 69 6e 74 20 6e 44  *aData;.  int nD
45d0: 61 74 61 3b 0a 20 20 75 38 20 2a 61 43 65 6c 6c  ata;.  u8 *aCell
45e0: 3b 0a 0a 20 20 61 44 61 74 61 20 3d 20 66 73 50  ;..  aData = fsP
45f0: 61 67 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44  ageData(pPg, &nD
4600: 61 74 61 29 3b 0a 20 20 61 43 65 6c 6c 20 3d 20  ata);.  aCell = 
4610: 70 61 67 65 47 65 74 43 65 6c 6c 28 61 44 61 74  pageGetCell(aDat
4620: 61 2c 20 6e 44 61 74 61 2c 20 69 4b 65 79 29 3b  a, nData, iKey);
4630: 0a 20 20 61 73 73 65 72 74 28 20 61 43 65 6c 6c  .  assert( aCell
4640: 5b 30 5d 3d 3d 30 20 29 3b 0a 20 20 61 43 65 6c  [0]==0 );.  aCel
4650: 6c 2b 2b 3b 0a 20 20 61 43 65 6c 6c 20 2b 3d 20  l++;.  aCell += 
4660: 6c 73 6d 56 61 72 69 6e 74 47 65 74 36 34 28 61  lsmVarintGet64(a
4670: 43 65 6c 6c 2c 20 26 69 52 65 66 29 3b 0a 20 20  Cell, &iRef);.  
4680: 6c 73 6d 56 61 72 69 6e 74 47 65 74 36 34 28 61  lsmVarintGet64(a
4690: 43 65 6c 6c 2c 20 26 69 52 65 66 29 3b 0a 20 20  Cell, &iRef);.  
46a0: 61 73 73 65 72 74 28 20 69 52 65 66 3e 30 20 29  assert( iRef>0 )
46b0: 3b 0a 20 20 72 65 74 75 72 6e 20 69 52 65 66 3b  ;.  return iRef;
46c0: 0a 7d 0a 0a 23 64 65 66 69 6e 65 20 47 45 54 56  .}..#define GETV
46d0: 41 52 49 4e 54 36 34 28 61 2c 20 69 29 20 28 28  ARINT64(a, i) ((
46e0: 28 69 29 3d 28 28 75 38 2a 29 28 61 29 29 5b 30  (i)=((u8*)(a))[0
46f0: 5d 29 3c 3d 32 34 30 3f 31 3a 6c 73 6d 56 61 72  ])<=240?1:lsmVar
4700: 69 6e 74 47 65 74 36 34 28 28 61 29 2c 20 26 28  intGet64((a), &(
4710: 69 29 29 29 0a 23 64 65 66 69 6e 65 20 47 45 54  i))).#define GET
4720: 56 41 52 49 4e 54 33 32 28 61 2c 20 69 29 20 28  VARINT32(a, i) (
4730: 28 28 69 29 3d 28 28 75 38 2a 29 28 61 29 29 5b  ((i)=((u8*)(a))[
4740: 30 5d 29 3c 3d 32 34 30 3f 31 3a 6c 73 6d 56 61  0])<=240?1:lsmVa
4750: 72 69 6e 74 47 65 74 33 32 28 28 61 29 2c 20 26  rintGet32((a), &
4760: 28 69 29 29 29 0a 0a 73 74 61 74 69 63 20 69 6e  (i)))..static in
4770: 74 20 70 61 67 65 47 65 74 42 74 72 65 65 4b 65  t pageGetBtreeKe
4780: 79 28 0a 20 20 53 65 67 6d 65 6e 74 20 2a 70 53  y(.  Segment *pS
4790: 65 67 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  eg,             
47a0: 20 20 20 20 20 2f 2a 20 53 65 67 6d 65 6e 74 20       /* Segment 
47b0: 70 61 67 65 20 70 50 67 20 62 65 6c 6f 6e 67 73  page pPg belongs
47c0: 20 74 6f 20 2a 2f 0a 20 20 50 61 67 65 20 2a 70   to */.  Page *p
47d0: 50 67 2c 0a 20 20 69 6e 74 20 69 4b 65 79 2c 20  Pg,.  int iKey, 
47e0: 0a 20 20 4c 73 6d 50 67 6e 6f 20 2a 70 69 50 74  .  LsmPgno *piPt
47f0: 72 2c 20 0a 20 20 69 6e 74 20 2a 70 69 54 6f 70  r, .  int *piTop
4800: 69 63 2c 20 0a 20 20 76 6f 69 64 20 2a 2a 70 70  ic, .  void **pp
4810: 4b 65 79 2c 0a 20 20 69 6e 74 20 2a 70 6e 4b 65  Key,.  int *pnKe
4820: 79 2c 0a 20 20 4c 73 6d 42 6c 6f 62 20 2a 70 42  y,.  LsmBlob *pB
4830: 6c 6f 62 0a 29 7b 0a 20 20 75 38 20 2a 61 44 61  lob.){.  u8 *aDa
4840: 74 61 3b 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b  ta;.  int nData;
4850: 0a 20 20 75 38 20 2a 61 43 65 6c 6c 3b 0a 20 20  .  u8 *aCell;.  
4860: 69 6e 74 20 65 54 79 70 65 3b 0a 0a 20 20 61 44  int eType;..  aD
4870: 61 74 61 20 3d 20 66 73 50 61 67 65 44 61 74 61  ata = fsPageData
4880: 28 70 50 67 2c 20 26 6e 44 61 74 61 29 3b 0a 20  (pPg, &nData);. 
4890: 20 61 73 73 65 72 74 28 20 53 45 47 4d 45 4e 54   assert( SEGMENT
48a0: 5f 42 54 52 45 45 5f 46 4c 41 47 20 26 20 70 61  _BTREE_FLAG & pa
48b0: 67 65 47 65 74 46 6c 61 67 73 28 61 44 61 74 61  geGetFlags(aData
48c0: 2c 20 6e 44 61 74 61 29 20 29 3b 0a 20 20 61 73  , nData) );.  as
48d0: 73 65 72 74 28 20 69 4b 65 79 3e 3d 30 20 26 26  sert( iKey>=0 &&
48e0: 20 69 4b 65 79 3c 70 61 67 65 47 65 74 4e 52 65   iKey<pageGetNRe
48f0: 63 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29 20  c(aData, nData) 
4900: 29 3b 0a 0a 20 20 61 43 65 6c 6c 20 3d 20 70 61  );..  aCell = pa
4910: 67 65 47 65 74 43 65 6c 6c 28 61 44 61 74 61 2c  geGetCell(aData,
4920: 20 6e 44 61 74 61 2c 20 69 4b 65 79 29 3b 0a 20   nData, iKey);. 
4930: 20 65 54 79 70 65 20 3d 20 2a 61 43 65 6c 6c 2b   eType = *aCell+
4940: 2b 3b 0a 20 20 61 43 65 6c 6c 20 2b 3d 20 47 45  +;.  aCell += GE
4950: 54 56 41 52 49 4e 54 36 34 28 61 43 65 6c 6c 2c  TVARINT64(aCell,
4960: 20 2a 70 69 50 74 72 29 3b 0a 0a 20 20 69 66 28   *piPtr);..  if(
4970: 20 65 54 79 70 65 3d 3d 30 20 29 7b 0a 20 20 20   eType==0 ){.   
4980: 20 69 6e 74 20 72 63 3b 0a 20 20 20 20 4c 73 6d   int rc;.    Lsm
4990: 50 67 6e 6f 20 69 52 65 66 3b 20 20 20 20 20 20  Pgno iRef;      
49a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65           /* Page
49b0: 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 66 65 72   number of refer
49c0: 65 6e 63 65 64 20 70 61 67 65 20 2a 2f 0a 20 20  enced page */.  
49d0: 20 20 50 61 67 65 20 2a 70 52 65 66 3b 0a 20 20    Page *pRef;.  
49e0: 20 20 61 43 65 6c 6c 20 2b 3d 20 47 45 54 56 41    aCell += GETVA
49f0: 52 49 4e 54 36 34 28 61 43 65 6c 6c 2c 20 69 52  RINT64(aCell, iR
4a00: 65 66 29 3b 0a 20 20 20 20 72 63 20 3d 20 6c 73  ef);.    rc = ls
4a10: 6d 46 73 44 62 50 61 67 65 47 65 74 28 6c 73 6d  mFsDbPageGet(lsm
4a20: 50 61 67 65 46 53 28 70 50 67 29 2c 20 70 53 65  PageFS(pPg), pSe
4a30: 67 2c 20 69 52 65 66 2c 20 26 70 52 65 66 29 3b  g, iRef, &pRef);
4a40: 0a 20 20 20 20 69 66 28 20 72 63 21 3d 4c 53 4d  .    if( rc!=LSM
4a50: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
4a60: 0a 20 20 20 20 70 61 67 65 47 65 74 4b 65 79 43  .    pageGetKeyC
4a70: 6f 70 79 28 6c 73 6d 50 61 67 65 45 6e 76 28 70  opy(lsmPageEnv(p
4a80: 50 67 29 2c 20 70 53 65 67 2c 20 70 52 65 66 2c  Pg), pSeg, pRef,
4a90: 20 30 2c 20 26 65 54 79 70 65 2c 20 70 42 6c 6f   0, &eType, pBlo
4aa0: 62 29 3b 0a 20 20 20 20 6c 73 6d 46 73 50 61 67  b);.    lsmFsPag
4ab0: 65 52 65 6c 65 61 73 65 28 70 52 65 66 29 3b 0a  eRelease(pRef);.
4ac0: 20 20 20 20 2a 70 70 4b 65 79 20 3d 20 70 42 6c      *ppKey = pBl
4ad0: 6f 62 2d 3e 70 44 61 74 61 3b 0a 20 20 20 20 2a  ob->pData;.    *
4ae0: 70 6e 4b 65 79 20 3d 20 70 42 6c 6f 62 2d 3e 6e  pnKey = pBlob->n
4af0: 44 61 74 61 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Data;.  }else{. 
4b00: 20 20 20 61 43 65 6c 6c 20 2b 3d 20 47 45 54 56     aCell += GETV
4b10: 41 52 49 4e 54 33 32 28 61 43 65 6c 6c 2c 20 2a  ARINT32(aCell, *
4b20: 70 6e 4b 65 79 29 3b 0a 20 20 20 20 2a 70 70 4b  pnKey);.    *ppK
4b30: 65 79 20 3d 20 61 43 65 6c 6c 3b 0a 20 20 7d 0a  ey = aCell;.  }.
4b40: 20 20 69 66 28 20 70 69 54 6f 70 69 63 20 29 20    if( piTopic ) 
4b50: 2a 70 69 54 6f 70 69 63 20 3d 20 72 74 54 6f 70  *piTopic = rtTop
4b60: 69 63 28 65 54 79 70 65 29 3b 0a 0a 20 20 72 65  ic(eType);..  re
4b70: 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 7d 0a 0a  turn LSM_OK;.}..
4b80: 73 74 61 74 69 63 20 69 6e 74 20 62 74 72 65 65  static int btree
4b90: 43 75 72 73 6f 72 4c 6f 61 64 4b 65 79 28 42 74  CursorLoadKey(Bt
4ba0: 72 65 65 43 75 72 73 6f 72 20 2a 70 43 73 72 29  reeCursor *pCsr)
4bb0: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d  {.  int rc = LSM
4bc0: 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 43 73 72 2d  _OK;.  if( pCsr-
4bd0: 3e 69 50 67 3c 30 20 29 7b 0a 20 20 20 20 70 43  >iPg<0 ){.    pC
4be0: 73 72 2d 3e 70 4b 65 79 20 3d 20 30 3b 0a 20 20  sr->pKey = 0;.  
4bf0: 20 20 70 43 73 72 2d 3e 6e 4b 65 79 20 3d 20 30    pCsr->nKey = 0
4c00: 3b 0a 20 20 20 20 70 43 73 72 2d 3e 65 54 79 70  ;.    pCsr->eTyp
4c10: 65 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a  e = 0;.  }else{.
4c20: 20 20 20 20 4c 73 6d 50 67 6e 6f 20 64 75 6d 6d      LsmPgno dumm
4c30: 79 3b 0a 20 20 20 20 69 6e 74 20 69 50 67 20 3d  y;.    int iPg =
4c40: 20 70 43 73 72 2d 3e 69 50 67 3b 0a 20 20 20 20   pCsr->iPg;.    
4c50: 69 6e 74 20 69 43 65 6c 6c 20 3d 20 70 43 73 72  int iCell = pCsr
4c60: 2d 3e 61 50 67 5b 69 50 67 5d 2e 69 43 65 6c 6c  ->aPg[iPg].iCell
4c70: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 43 65  ;.    while( iCe
4c80: 6c 6c 3c 30 20 26 26 20 28 2d 2d 69 50 67 29 3e  ll<0 && (--iPg)>
4c90: 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 43 65 6c  =0 ){.      iCel
4ca0: 6c 20 3d 20 70 43 73 72 2d 3e 61 50 67 5b 69 50  l = pCsr->aPg[iP
4cb0: 67 5d 2e 69 43 65 6c 6c 2d 31 3b 0a 20 20 20 20  g].iCell-1;.    
4cc0: 7d 0a 20 20 20 20 69 66 28 20 69 50 67 3c 30 20  }.    if( iPg<0 
4cd0: 7c 7c 20 69 43 65 6c 6c 3c 30 20 29 20 72 65 74  || iCell<0 ) ret
4ce0: 75 72 6e 20 4c 53 4d 5f 43 4f 52 52 55 50 54 5f  urn LSM_CORRUPT_
4cf0: 42 4b 50 54 3b 0a 0a 20 20 20 20 72 63 20 3d 20  BKPT;..    rc = 
4d00: 70 61 67 65 47 65 74 42 74 72 65 65 4b 65 79 28  pageGetBtreeKey(
4d10: 0a 20 20 20 20 20 20 20 20 70 43 73 72 2d 3e 70  .        pCsr->p
4d20: 53 65 67 2c 0a 20 20 20 20 20 20 20 20 70 43 73  Seg,.        pCs
4d30: 72 2d 3e 61 50 67 5b 69 50 67 5d 2e 70 50 61 67  r->aPg[iPg].pPag
4d40: 65 2c 20 69 43 65 6c 6c 2c 0a 20 20 20 20 20 20  e, iCell,.      
4d50: 20 20 26 64 75 6d 6d 79 2c 20 26 70 43 73 72 2d    &dummy, &pCsr-
4d60: 3e 65 54 79 70 65 2c 20 26 70 43 73 72 2d 3e 70  >eType, &pCsr->p
4d70: 4b 65 79 2c 20 26 70 43 73 72 2d 3e 6e 4b 65 79  Key, &pCsr->nKey
4d80: 2c 20 26 70 43 73 72 2d 3e 62 6c 6f 62 0a 20 20  , &pCsr->blob.  
4d90: 20 20 29 3b 0a 20 20 20 20 70 43 73 72 2d 3e 65    );.    pCsr->e
4da0: 54 79 70 65 20 7c 3d 20 4c 53 4d 5f 53 45 50 41  Type |= LSM_SEPA
4db0: 52 41 54 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72 65  RATOR;.  }..  re
4dc0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
4dd0: 69 63 20 69 6e 74 20 62 74 72 65 65 43 75 72 73  ic int btreeCurs
4de0: 6f 72 50 74 72 28 75 38 20 2a 61 44 61 74 61 2c  orPtr(u8 *aData,
4df0: 20 69 6e 74 20 6e 44 61 74 61 2c 20 69 6e 74 20   int nData, int 
4e00: 69 43 65 6c 6c 29 7b 0a 20 20 69 6e 74 20 6e 43  iCell){.  int nC
4e10: 65 6c 6c 3b 0a 0a 20 20 6e 43 65 6c 6c 20 3d 20  ell;..  nCell = 
4e20: 70 61 67 65 47 65 74 4e 52 65 63 28 61 44 61 74  pageGetNRec(aDat
4e30: 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 69 66 28  a, nData);.  if(
4e40: 20 69 43 65 6c 6c 3e 3d 6e 43 65 6c 6c 20 29 7b   iCell>=nCell ){
4e50: 0a 20 20 20 20 72 65 74 75 72 6e 20 28 69 6e 74  .    return (int
4e60: 29 70 61 67 65 47 65 74 50 74 72 28 61 44 61 74  )pageGetPtr(aDat
4e70: 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 7d 0a 20  a, nData);.  }. 
4e80: 20 72 65 74 75 72 6e 20 28 69 6e 74 29 70 61 67   return (int)pag
4e90: 65 47 65 74 52 65 63 6f 72 64 50 74 72 28 61 44  eGetRecordPtr(aD
4ea0: 61 74 61 2c 20 6e 44 61 74 61 2c 20 69 43 65 6c  ata, nData, iCel
4eb0: 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  l);.}..static in
4ec0: 74 20 62 74 72 65 65 43 75 72 73 6f 72 4e 65 78  t btreeCursorNex
4ed0: 74 28 42 74 72 65 65 43 75 72 73 6f 72 20 2a 70  t(BtreeCursor *p
4ee0: 43 73 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  Csr){.  int rc =
4ef0: 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20 20 42 74 72 65   LSM_OK;..  Btre
4f00: 65 50 67 20 2a 70 50 67 20 3d 20 26 70 43 73 72  ePg *pPg = &pCsr
4f10: 2d 3e 61 50 67 5b 70 43 73 72 2d 3e 69 50 67 5d  ->aPg[pCsr->iPg]
4f20: 3b 0a 20 20 69 6e 74 20 6e 43 65 6c 6c 3b 20 0a  ;.  int nCell; .
4f30: 20 20 75 38 20 2a 61 44 61 74 61 3b 0a 20 20 69    u8 *aData;.  i
4f40: 6e 74 20 6e 44 61 74 61 3b 0a 0a 20 20 61 73 73  nt nData;..  ass
4f50: 65 72 74 28 20 70 43 73 72 2d 3e 69 50 67 3e 3d  ert( pCsr->iPg>=
4f60: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  0 );.  assert( p
4f70: 43 73 72 2d 3e 69 50 67 3d 3d 70 43 73 72 2d 3e  Csr->iPg==pCsr->
4f80: 6e 44 65 70 74 68 2d 31 20 29 3b 0a 0a 20 20 61  nDepth-1 );..  a
4f90: 44 61 74 61 20 3d 20 66 73 50 61 67 65 44 61 74  Data = fsPageDat
4fa0: 61 28 70 50 67 2d 3e 70 50 61 67 65 2c 20 26 6e  a(pPg->pPage, &n
4fb0: 44 61 74 61 29 3b 0a 20 20 6e 43 65 6c 6c 20 3d  Data);.  nCell =
4fc0: 20 70 61 67 65 47 65 74 4e 52 65 63 28 61 44 61   pageGetNRec(aDa
4fd0: 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 61 73  ta, nData);.  as
4fe0: 73 65 72 74 28 20 70 50 67 2d 3e 69 43 65 6c 6c  sert( pPg->iCell
4ff0: 3c 3d 6e 43 65 6c 6c 20 29 3b 0a 20 20 70 50 67  <=nCell );.  pPg
5000: 2d 3e 69 43 65 6c 6c 2b 2b 3b 0a 20 20 69 66 28  ->iCell++;.  if(
5010: 20 70 50 67 2d 3e 69 43 65 6c 6c 3d 3d 6e 43 65   pPg->iCell==nCe
5020: 6c 6c 20 29 7b 0a 20 20 20 20 4c 73 6d 50 67 6e  ll ){.    LsmPgn
5030: 6f 20 69 4c 6f 61 64 3b 0a 0a 20 20 20 20 2f 2a  o iLoad;..    /*
5040: 20 55 70 20 74 6f 20 70 61 72 65 6e 74 2e 20 2a   Up to parent. *
5050: 2f 0a 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52  /.    lsmFsPageR
5060: 65 6c 65 61 73 65 28 70 50 67 2d 3e 70 50 61 67  elease(pPg->pPag
5070: 65 29 3b 0a 20 20 20 20 70 50 67 2d 3e 70 50 61  e);.    pPg->pPa
5080: 67 65 20 3d 20 30 3b 0a 20 20 20 20 70 43 73 72  ge = 0;.    pCsr
5090: 2d 3e 69 50 67 2d 2d 3b 0a 20 20 20 20 77 68 69  ->iPg--;.    whi
50a0: 6c 65 28 20 70 43 73 72 2d 3e 69 50 67 3e 3d 30  le( pCsr->iPg>=0
50b0: 20 29 7b 0a 20 20 20 20 20 20 70 50 67 20 3d 20   ){.      pPg = 
50c0: 26 70 43 73 72 2d 3e 61 50 67 5b 70 43 73 72 2d  &pCsr->aPg[pCsr-
50d0: 3e 69 50 67 5d 3b 0a 20 20 20 20 20 20 61 44 61  >iPg];.      aDa
50e0: 74 61 20 3d 20 66 73 50 61 67 65 44 61 74 61 28  ta = fsPageData(
50f0: 70 50 67 2d 3e 70 50 61 67 65 2c 20 26 6e 44 61  pPg->pPage, &nDa
5100: 74 61 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  ta);.      if( p
5110: 50 67 2d 3e 69 43 65 6c 6c 3c 70 61 67 65 47 65  Pg->iCell<pageGe
5120: 74 4e 52 65 63 28 61 44 61 74 61 2c 20 6e 44 61  tNRec(aData, nDa
5130: 74 61 29 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  ta) ) break;.   
5140: 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65     lsmFsPageRele
5150: 61 73 65 28 70 50 67 2d 3e 70 50 61 67 65 29 3b  ase(pPg->pPage);
5160: 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 69 50 67  .      pCsr->iPg
5170: 2d 2d 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  --;.    }..    /
5180: 2a 20 52 65 61 64 20 74 68 65 20 6b 65 79 20 2a  * Read the key *
5190: 2f 0a 20 20 20 20 72 63 20 3d 20 62 74 72 65 65  /.    rc = btree
51a0: 43 75 72 73 6f 72 4c 6f 61 64 4b 65 79 28 70 43  CursorLoadKey(pC
51b0: 73 72 29 3b 0a 0a 20 20 20 20 2f 2a 20 55 6e 6c  sr);..    /* Unl
51c0: 65 73 73 20 74 68 65 20 63 75 72 73 6f 72 20 69  ess the cursor i
51d0: 73 20 61 74 20 45 4f 46 2c 20 64 65 73 63 65 6e  s at EOF, descen
51e0: 64 20 74 6f 20 63 65 6c 6c 20 2d 31 20 28 79 65  d to cell -1 (ye
51f0: 73 2c 20 6e 65 67 61 74 69 76 65 20 6f 6e 65 29  s, negative one)
5200: 20 6f 66 20 0a 20 20 20 20 2a 2a 20 74 68 65 20   of .    ** the 
5210: 6c 65 66 74 2d 6d 6f 73 74 20 6d 6f 73 74 20 64  left-most most d
5220: 65 73 63 65 6e 64 65 6e 74 2e 20 2a 2f 0a 20 20  escendent. */.  
5230: 20 20 69 66 28 20 70 43 73 72 2d 3e 69 50 67 3e    if( pCsr->iPg>
5240: 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 43 73 72  =0 ){.      pCsr
5250: 2d 3e 61 50 67 5b 70 43 73 72 2d 3e 69 50 67 5d  ->aPg[pCsr->iPg]
5260: 2e 69 43 65 6c 6c 2b 2b 3b 0a 0a 20 20 20 20 20  .iCell++;..     
5270: 20 69 4c 6f 61 64 20 3d 20 62 74 72 65 65 43 75   iLoad = btreeCu
5280: 72 73 6f 72 50 74 72 28 61 44 61 74 61 2c 20 6e  rsorPtr(aData, n
5290: 44 61 74 61 2c 20 70 50 67 2d 3e 69 43 65 6c 6c  Data, pPg->iCell
52a0: 29 3b 0a 20 20 20 20 20 20 64 6f 20 7b 0a 20 20  );.      do {.  
52b0: 20 20 20 20 20 20 50 61 67 65 20 2a 70 4c 6f 61        Page *pLoa
52c0: 64 3b 0a 20 20 20 20 20 20 20 20 70 43 73 72 2d  d;.        pCsr-
52d0: 3e 69 50 67 2b 2b 3b 0a 20 20 20 20 20 20 20 20  >iPg++;.        
52e0: 72 63 20 3d 20 6c 73 6d 46 73 44 62 50 61 67 65  rc = lsmFsDbPage
52f0: 47 65 74 28 70 43 73 72 2d 3e 70 46 53 2c 20 70  Get(pCsr->pFS, p
5300: 43 73 72 2d 3e 70 53 65 67 2c 20 69 4c 6f 61 64  Csr->pSeg, iLoad
5310: 2c 20 26 70 4c 6f 61 64 29 3b 0a 20 20 20 20 20  , &pLoad);.     
5320: 20 20 20 70 43 73 72 2d 3e 61 50 67 5b 70 43 73     pCsr->aPg[pCs
5330: 72 2d 3e 69 50 67 5d 2e 70 50 61 67 65 20 3d 20  r->iPg].pPage = 
5340: 70 4c 6f 61 64 3b 0a 20 20 20 20 20 20 20 20 70  pLoad;.        p
5350: 43 73 72 2d 3e 61 50 67 5b 70 43 73 72 2d 3e 69  Csr->aPg[pCsr->i
5360: 50 67 5d 2e 69 43 65 6c 6c 20 3d 20 30 3b 0a 20  Pg].iCell = 0;. 
5370: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c         if( rc==L
5380: 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  SM_OK ){.       
5390: 20 20 20 69 66 28 20 70 43 73 72 2d 3e 69 50 67     if( pCsr->iPg
53a0: 3d 3d 28 70 43 73 72 2d 3e 6e 44 65 70 74 68 2d  ==(pCsr->nDepth-
53b0: 31 29 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  1) ) break;.    
53c0: 20 20 20 20 20 20 61 44 61 74 61 20 3d 20 66 73        aData = fs
53d0: 50 61 67 65 44 61 74 61 28 70 4c 6f 61 64 2c 20  PageData(pLoad, 
53e0: 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20 20  &nData);.       
53f0: 20 20 20 69 4c 6f 61 64 20 3d 20 62 74 72 65 65     iLoad = btree
5400: 43 75 72 73 6f 72 50 74 72 28 61 44 61 74 61 2c  CursorPtr(aData,
5410: 20 6e 44 61 74 61 2c 20 30 29 3b 0a 20 20 20 20   nData, 0);.    
5420: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 77 68 69      }.      }whi
5430: 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26  le( rc==LSM_OK &
5440: 26 20 70 43 73 72 2d 3e 69 50 67 3c 28 70 43 73  & pCsr->iPg<(pCs
5450: 72 2d 3e 6e 44 65 70 74 68 2d 31 29 20 29 3b 0a  r->nDepth-1) );.
5460: 20 20 20 20 20 20 70 43 73 72 2d 3e 61 50 67 5b        pCsr->aPg[
5470: 70 43 73 72 2d 3e 69 50 67 5d 2e 69 43 65 6c 6c  pCsr->iPg].iCell
5480: 20 3d 20 2d 31 3b 0a 20 20 20 20 7d 0a 0a 20 20   = -1;.    }..  
5490: 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20  }else{.    rc = 
54a0: 62 74 72 65 65 43 75 72 73 6f 72 4c 6f 61 64 4b  btreeCursorLoadK
54b0: 65 79 28 70 43 73 72 29 3b 0a 20 20 7d 0a 0a 20  ey(pCsr);.  }.. 
54c0: 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
54d0: 26 26 20 70 43 73 72 2d 3e 69 50 67 3e 3d 30 20  && pCsr->iPg>=0 
54e0: 29 7b 0a 20 20 20 20 61 44 61 74 61 20 3d 20 66  ){.    aData = f
54f0: 73 50 61 67 65 44 61 74 61 28 70 43 73 72 2d 3e  sPageData(pCsr->
5500: 61 50 67 5b 70 43 73 72 2d 3e 69 50 67 5d 2e 70  aPg[pCsr->iPg].p
5510: 50 61 67 65 2c 20 26 6e 44 61 74 61 29 3b 0a 20  Page, &nData);. 
5520: 20 20 20 70 43 73 72 2d 3e 69 50 74 72 20 3d 20     pCsr->iPtr = 
5530: 62 74 72 65 65 43 75 72 73 6f 72 50 74 72 28 61  btreeCursorPtr(a
5540: 44 61 74 61 2c 20 6e 44 61 74 61 2c 20 70 43 73  Data, nData, pCs
5550: 72 2d 3e 61 50 67 5b 70 43 73 72 2d 3e 69 50 67  r->aPg[pCsr->iPg
5560: 5d 2e 69 43 65 6c 6c 2b 31 29 3b 0a 20 20 7d 0a  ].iCell+1);.  }.
5570: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
5580: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 62 74 72  .static void btr
5590: 65 65 43 75 72 73 6f 72 46 72 65 65 28 42 74 72  eeCursorFree(Btr
55a0: 65 65 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b  eeCursor *pCsr){
55b0: 0a 20 20 69 66 28 20 70 43 73 72 20 29 7b 0a 20  .  if( pCsr ){. 
55c0: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 6c 73     int i;.    ls
55d0: 6d 5f 65 6e 76 20 2a 70 45 6e 76 20 3d 20 6c 73  m_env *pEnv = ls
55e0: 6d 46 73 45 6e 76 28 70 43 73 72 2d 3e 70 46 53  mFsEnv(pCsr->pFS
55f0: 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  );.    for(i=0; 
5600: 69 3c 3d 70 43 73 72 2d 3e 69 50 67 3b 20 69 2b  i<=pCsr->iPg; i+
5610: 2b 29 7b 0a 20 20 20 20 20 20 6c 73 6d 46 73 50  +){.      lsmFsP
5620: 61 67 65 52 65 6c 65 61 73 65 28 70 43 73 72 2d  ageRelease(pCsr-
5630: 3e 61 50 67 5b 69 5d 2e 70 50 61 67 65 29 3b 0a  >aPg[i].pPage);.
5640: 20 20 20 20 7d 0a 20 20 20 20 73 6f 72 74 65 64      }.    sorted
5650: 42 6c 6f 62 46 72 65 65 28 26 70 43 73 72 2d 3e  BlobFree(&pCsr->
5660: 62 6c 6f 62 29 3b 0a 20 20 20 20 6c 73 6d 46 72  blob);.    lsmFr
5670: 65 65 28 70 45 6e 76 2c 20 70 43 73 72 2d 3e 61  ee(pEnv, pCsr->a
5680: 50 67 29 3b 0a 20 20 20 20 6c 73 6d 46 72 65 65  Pg);.    lsmFree
5690: 28 70 45 6e 76 2c 20 70 43 73 72 29 3b 0a 20 20  (pEnv, pCsr);.  
56a0: 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  }.}..static int 
56b0: 62 74 72 65 65 43 75 72 73 6f 72 46 69 72 73 74  btreeCursorFirst
56c0: 28 42 74 72 65 65 43 75 72 73 6f 72 20 2a 70 43  (BtreeCursor *pC
56d0: 73 72 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a  sr){.  int rc;..
56e0: 20 20 50 61 67 65 20 2a 70 50 67 20 3d 20 30 3b    Page *pPg = 0;
56f0: 0a 20 20 46 69 6c 65 53 79 73 74 65 6d 20 2a 70  .  FileSystem *p
5700: 46 53 20 3d 20 70 43 73 72 2d 3e 70 46 53 3b 0a  FS = pCsr->pFS;.
5710: 20 20 69 6e 74 20 69 50 67 20 3d 20 28 69 6e 74    int iPg = (int
5720: 29 70 43 73 72 2d 3e 70 53 65 67 2d 3e 69 52 6f  )pCsr->pSeg->iRo
5730: 6f 74 3b 0a 0a 20 20 64 6f 20 7b 0a 20 20 20 20  ot;..  do {.    
5740: 72 63 20 3d 20 6c 73 6d 46 73 44 62 50 61 67 65  rc = lsmFsDbPage
5750: 47 65 74 28 70 46 53 2c 20 70 43 73 72 2d 3e 70  Get(pFS, pCsr->p
5760: 53 65 67 2c 20 69 50 67 2c 20 26 70 50 67 29 3b  Seg, iPg, &pPg);
5770: 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 72 63  .    assert( (rc
5780: 3d 3d 4c 53 4d 5f 4f 4b 29 3d 3d 28 70 50 67 21  ==LSM_OK)==(pPg!
5790: 3d 30 29 20 29 3b 0a 20 20 20 20 69 66 28 20 72  =0) );.    if( r
57a0: 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
57b0: 20 20 20 75 38 20 2a 61 44 61 74 61 3b 0a 20 20     u8 *aData;.  
57c0: 20 20 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a 20      int nData;. 
57d0: 20 20 20 20 20 69 6e 74 20 66 6c 61 67 73 3b 0a       int flags;.
57e0: 0a 20 20 20 20 20 20 61 44 61 74 61 20 3d 20 66  .      aData = f
57f0: 73 50 61 67 65 44 61 74 61 28 70 50 67 2c 20 26  sPageData(pPg, &
5800: 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20 66 6c  nData);.      fl
5810: 61 67 73 20 3d 20 70 61 67 65 47 65 74 46 6c 61  ags = pageGetFla
5820: 67 73 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29  gs(aData, nData)
5830: 3b 0a 20 20 20 20 20 20 69 66 28 20 28 66 6c 61  ;.      if( (fla
5840: 67 73 20 26 20 53 45 47 4d 45 4e 54 5f 42 54 52  gs & SEGMENT_BTR
5850: 45 45 5f 46 4c 41 47 29 3d 3d 30 20 29 20 62 72  EE_FLAG)==0 ) br
5860: 65 61 6b 3b 0a 0a 20 20 20 20 20 20 69 66 28 20  eak;..      if( 
5870: 28 70 43 73 72 2d 3e 6e 44 65 70 74 68 20 25 20  (pCsr->nDepth % 
5880: 38 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  8)==0 ){.       
5890: 20 69 6e 74 20 6e 4e 65 77 20 3d 20 70 43 73 72   int nNew = pCsr
58a0: 2d 3e 6e 44 65 70 74 68 20 2b 20 38 3b 0a 20 20  ->nDepth + 8;.  
58b0: 20 20 20 20 20 20 70 43 73 72 2d 3e 61 50 67 20        pCsr->aPg 
58c0: 3d 20 28 42 74 72 65 65 50 67 20 2a 29 6c 73 6d  = (BtreePg *)lsm
58d0: 52 65 61 6c 6c 6f 63 4f 72 46 72 65 65 52 63 28  ReallocOrFreeRc(
58e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 73 6d  .            lsm
58f0: 46 73 45 6e 76 28 70 46 53 29 2c 20 70 43 73 72  FsEnv(pFS), pCsr
5900: 2d 3e 61 50 67 2c 20 73 69 7a 65 6f 66 28 42 74  ->aPg, sizeof(Bt
5910: 72 65 65 50 67 29 20 2a 20 6e 4e 65 77 2c 20 26  reePg) * nNew, &
5920: 72 63 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20  rc.        );.  
5930: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53        if( rc==LS
5940: 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  M_OK ){.        
5950: 20 20 6d 65 6d 73 65 74 28 26 70 43 73 72 2d 3e    memset(&pCsr->
5960: 61 50 67 5b 70 43 73 72 2d 3e 6e 44 65 70 74 68  aPg[pCsr->nDepth
5970: 5d 2c 20 30 2c 20 73 69 7a 65 6f 66 28 42 74 72  ], 0, sizeof(Btr
5980: 65 65 50 67 29 20 2a 20 38 29 3b 0a 20 20 20 20  eePg) * 8);.    
5990: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20      }.      }.. 
59a0: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d       if( rc==LSM
59b0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 61  _OK ){.        a
59c0: 73 73 65 72 74 28 20 70 43 73 72 2d 3e 61 50 67  ssert( pCsr->aPg
59d0: 5b 70 43 73 72 2d 3e 6e 44 65 70 74 68 5d 2e 69  [pCsr->nDepth].i
59e0: 43 65 6c 6c 3d 3d 30 20 29 3b 0a 20 20 20 20 20  Cell==0 );.     
59f0: 20 20 20 70 43 73 72 2d 3e 61 50 67 5b 70 43 73     pCsr->aPg[pCs
5a00: 72 2d 3e 6e 44 65 70 74 68 5d 2e 70 50 61 67 65  r->nDepth].pPage
5a10: 20 3d 20 70 50 67 3b 0a 20 20 20 20 20 20 20 20   = pPg;.        
5a20: 70 43 73 72 2d 3e 6e 44 65 70 74 68 2b 2b 3b 0a  pCsr->nDepth++;.
5a30: 20 20 20 20 20 20 20 20 69 50 67 20 3d 20 28 69          iPg = (i
5a40: 6e 74 29 70 61 67 65 47 65 74 52 65 63 6f 72 64  nt)pageGetRecord
5a50: 50 74 72 28 61 44 61 74 61 2c 20 6e 44 61 74 61  Ptr(aData, nData
5a60: 2c 20 30 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  , 0);.      }.  
5a70: 20 20 7d 0a 20 20 7d 77 68 69 6c 65 28 20 72 63    }.  }while( rc
5a80: 3d 3d 4c 53 4d 5f 4f 4b 20 29 3b 0a 20 20 6c 73  ==LSM_OK );.  ls
5a90: 6d 46 73 50 61 67 65 52 65 6c 65 61 73 65 28 70  mFsPageRelease(p
5aa0: 50 67 29 3b 0a 20 20 70 43 73 72 2d 3e 69 50 67  Pg);.  pCsr->iPg
5ab0: 20 3d 20 70 43 73 72 2d 3e 6e 44 65 70 74 68 2d   = pCsr->nDepth-
5ac0: 31 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53  1;..  if( rc==LS
5ad0: 4d 5f 4f 4b 20 26 26 20 70 43 73 72 2d 3e 6e 44  M_OK && pCsr->nD
5ae0: 65 70 74 68 20 29 7b 0a 20 20 20 20 70 43 73 72  epth ){.    pCsr
5af0: 2d 3e 61 50 67 5b 70 43 73 72 2d 3e 69 50 67 5d  ->aPg[pCsr->iPg]
5b00: 2e 69 43 65 6c 6c 20 3d 20 2d 31 3b 0a 20 20 20  .iCell = -1;.   
5b10: 20 72 63 20 3d 20 62 74 72 65 65 43 75 72 73 6f   rc = btreeCurso
5b20: 72 4e 65 78 74 28 70 43 73 72 29 3b 0a 20 20 7d  rNext(pCsr);.  }
5b30: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
5b40: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 62 74  ..static void bt
5b50: 72 65 65 43 75 72 73 6f 72 50 6f 73 69 74 69 6f  reeCursorPositio
5b60: 6e 28 42 74 72 65 65 43 75 72 73 6f 72 20 2a 70  n(BtreeCursor *p
5b70: 43 73 72 2c 20 4d 65 72 67 65 49 6e 70 75 74 20  Csr, MergeInput 
5b80: 2a 70 29 7b 0a 20 20 69 66 28 20 70 43 73 72 2d  *p){.  if( pCsr-
5b90: 3e 69 50 67 3e 3d 30 20 29 7b 0a 20 20 20 20 70  >iPg>=0 ){.    p
5ba0: 2d 3e 69 50 67 20 3d 20 6c 73 6d 46 73 50 61 67  ->iPg = lsmFsPag
5bb0: 65 4e 75 6d 62 65 72 28 70 43 73 72 2d 3e 61 50  eNumber(pCsr->aP
5bc0: 67 5b 70 43 73 72 2d 3e 69 50 67 5d 2e 70 50 61  g[pCsr->iPg].pPa
5bd0: 67 65 29 3b 0a 20 20 20 20 70 2d 3e 69 43 65 6c  ge);.    p->iCel
5be0: 6c 20 3d 20 28 28 70 43 73 72 2d 3e 61 50 67 5b  l = ((pCsr->aPg[
5bf0: 70 43 73 72 2d 3e 69 50 67 5d 2e 69 43 65 6c 6c  pCsr->iPg].iCell
5c00: 20 2b 20 31 29 20 3c 3c 20 38 29 20 2b 20 70 43   + 1) << 8) + pC
5c10: 73 72 2d 3e 6e 44 65 70 74 68 3b 0a 20 20 7d 65  sr->nDepth;.  }e
5c20: 6c 73 65 7b 0a 20 20 20 20 70 2d 3e 69 50 67 20  lse{.    p->iPg 
5c30: 3d 20 30 3b 0a 20 20 20 20 70 2d 3e 69 43 65 6c  = 0;.    p->iCel
5c40: 6c 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 73 74  l = 0;.  }.}..st
5c50: 61 74 69 63 20 76 6f 69 64 20 62 74 72 65 65 43  atic void btreeC
5c60: 75 72 73 6f 72 53 70 6c 69 74 6b 65 79 28 42 74  ursorSplitkey(Bt
5c70: 72 65 65 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  reeCursor *pCsr,
5c80: 20 4d 65 72 67 65 49 6e 70 75 74 20 2a 70 29 7b   MergeInput *p){
5c90: 0a 20 20 69 6e 74 20 69 43 65 6c 6c 20 3d 20 70  .  int iCell = p
5ca0: 43 73 72 2d 3e 61 50 67 5b 70 43 73 72 2d 3e 69  Csr->aPg[pCsr->i
5cb0: 50 67 5d 2e 69 43 65 6c 6c 3b 0a 20 20 69 66 28  Pg].iCell;.  if(
5cc0: 20 69 43 65 6c 6c 3e 3d 30 20 29 7b 0a 20 20 20   iCell>=0 ){.   
5cd0: 20 70 2d 3e 69 43 65 6c 6c 20 3d 20 69 43 65 6c   p->iCell = iCel
5ce0: 6c 3b 0a 20 20 20 20 70 2d 3e 69 50 67 20 3d 20  l;.    p->iPg = 
5cf0: 6c 73 6d 46 73 50 61 67 65 4e 75 6d 62 65 72 28  lsmFsPageNumber(
5d00: 70 43 73 72 2d 3e 61 50 67 5b 70 43 73 72 2d 3e  pCsr->aPg[pCsr->
5d10: 69 50 67 5d 2e 70 50 61 67 65 29 3b 0a 20 20 7d  iPg].pPage);.  }
5d20: 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 69 3b  else{.    int i;
5d30: 0a 20 20 20 20 66 6f 72 28 69 3d 70 43 73 72 2d  .    for(i=pCsr-
5d40: 3e 69 50 67 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d  >iPg-1; i>=0; i-
5d50: 2d 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 43  -){.      if( pC
5d60: 73 72 2d 3e 61 50 67 5b 69 5d 2e 69 43 65 6c 6c  sr->aPg[i].iCell
5d70: 3e 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  >0 ) break;.    
5d80: 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 69 3e  }.    assert( i>
5d90: 3d 30 20 29 3b 0a 20 20 20 20 70 2d 3e 69 43 65  =0 );.    p->iCe
5da0: 6c 6c 20 3d 20 70 43 73 72 2d 3e 61 50 67 5b 69  ll = pCsr->aPg[i
5db0: 5d 2e 69 43 65 6c 6c 2d 31 3b 0a 20 20 20 20 70  ].iCell-1;.    p
5dc0: 2d 3e 69 50 67 20 3d 20 6c 73 6d 46 73 50 61 67  ->iPg = lsmFsPag
5dd0: 65 4e 75 6d 62 65 72 28 70 43 73 72 2d 3e 61 50  eNumber(pCsr->aP
5de0: 67 5b 69 5d 2e 70 50 61 67 65 29 3b 0a 20 20 7d  g[i].pPage);.  }
5df0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .}..static int s
5e00: 6f 72 74 65 64 4b 65 79 43 6f 6d 70 61 72 65 28  ortedKeyCompare(
5e10: 0a 20 20 69 6e 74 20 28 2a 78 43 6d 70 29 28 76  .  int (*xCmp)(v
5e20: 6f 69 64 20 2a 2c 20 69 6e 74 2c 20 76 6f 69 64  oid *, int, void
5e30: 20 2a 2c 20 69 6e 74 29 2c 0a 20 20 69 6e 74 20   *, int),.  int 
5e40: 69 4c 68 73 54 6f 70 69 63 2c 20 76 6f 69 64 20  iLhsTopic, void 
5e50: 2a 70 4c 68 73 4b 65 79 2c 20 69 6e 74 20 6e 4c  *pLhsKey, int nL
5e60: 68 73 4b 65 79 2c 0a 20 20 69 6e 74 20 69 52 68  hsKey,.  int iRh
5e70: 73 54 6f 70 69 63 2c 20 76 6f 69 64 20 2a 70 52  sTopic, void *pR
5e80: 68 73 4b 65 79 2c 20 69 6e 74 20 6e 52 68 73 4b  hsKey, int nRhsK
5e90: 65 79 0a 29 7b 0a 20 20 69 6e 74 20 72 65 73 20  ey.){.  int res 
5ea0: 3d 20 69 4c 68 73 54 6f 70 69 63 20 2d 20 69 52  = iLhsTopic - iR
5eb0: 68 73 54 6f 70 69 63 3b 0a 20 20 69 66 28 20 72  hsTopic;.  if( r
5ec0: 65 73 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 73  es==0 ){.    res
5ed0: 20 3d 20 78 43 6d 70 28 70 4c 68 73 4b 65 79 2c   = xCmp(pLhsKey,
5ee0: 20 6e 4c 68 73 4b 65 79 2c 20 70 52 68 73 4b 65   nLhsKey, pRhsKe
5ef0: 79 2c 20 6e 52 68 73 4b 65 79 29 3b 0a 20 20 7d  y, nRhsKey);.  }
5f00: 0a 20 20 72 65 74 75 72 6e 20 72 65 73 3b 0a 7d  .  return res;.}
5f10: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 62 74 72  ..static int btr
5f20: 65 65 43 75 72 73 6f 72 52 65 73 74 6f 72 65 28  eeCursorRestore(
5f30: 0a 20 20 42 74 72 65 65 43 75 72 73 6f 72 20 2a  .  BtreeCursor *
5f40: 70 43 73 72 2c 20 0a 20 20 69 6e 74 20 28 2a 78  pCsr, .  int (*x
5f50: 43 6d 70 29 28 76 6f 69 64 20 2a 2c 20 69 6e 74  Cmp)(void *, int
5f60: 2c 20 76 6f 69 64 20 2a 2c 20 69 6e 74 29 2c 0a  , void *, int),.
5f70: 20 20 4d 65 72 67 65 49 6e 70 75 74 20 2a 70 0a    MergeInput *p.
5f80: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53  ){.  int rc = LS
5f90: 4d 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 70 2d 3e  M_OK;..  if( p->
5fa0: 69 50 67 20 29 7b 0a 20 20 20 20 6c 73 6d 5f 65  iPg ){.    lsm_e
5fb0: 6e 76 20 2a 70 45 6e 76 20 3d 20 6c 73 6d 46 73  nv *pEnv = lsmFs
5fc0: 45 6e 76 28 70 43 73 72 2d 3e 70 46 53 29 3b 0a  Env(pCsr->pFS);.
5fd0: 20 20 20 20 69 6e 74 20 69 43 65 6c 6c 3b 20 20      int iCell;  
5fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ff0: 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 63 65 6c    /* Current cel
6000: 6c 20 6e 75 6d 62 65 72 20 6f 6e 20 6c 65 61 66  l number on leaf
6010: 20 70 61 67 65 20 2a 2f 0a 20 20 20 20 4c 73 6d   page */.    Lsm
6020: 50 67 6e 6f 20 69 4c 65 61 66 3b 20 20 20 20 20  Pgno iLeaf;     
6030: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
6040: 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 63 75 72  ge number of cur
6050: 72 65 6e 74 20 6c 65 61 66 20 70 61 67 65 20 2a  rent leaf page *
6060: 2f 0a 20 20 20 20 69 6e 74 20 6e 44 65 70 74 68  /.    int nDepth
6070: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
6080: 20 20 20 20 2f 2a 20 44 65 70 74 68 20 6f 66 20      /* Depth of 
6090: 62 2d 74 72 65 65 20 73 74 72 75 63 74 75 72 65  b-tree structure
60a0: 20 2a 2f 0a 20 20 20 20 53 65 67 6d 65 6e 74 20   */.    Segment 
60b0: 2a 70 53 65 67 20 3d 20 70 43 73 72 2d 3e 70 53  *pSeg = pCsr->pS
60c0: 65 67 3b 0a 0a 20 20 20 20 2f 2a 20 44 65 63 6f  eg;..    /* Deco
60d0: 64 65 20 74 68 65 20 4d 65 72 67 65 49 6e 70 75  de the MergeInpu
60e0: 74 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a 20  t structure */. 
60f0: 20 20 20 69 4c 65 61 66 20 3d 20 70 2d 3e 69 50     iLeaf = p->iP
6100: 67 3b 0a 20 20 20 20 6e 44 65 70 74 68 20 3d 20  g;.    nDepth = 
6110: 28 70 2d 3e 69 43 65 6c 6c 20 26 20 30 78 30 30  (p->iCell & 0x00
6120: 46 46 29 3b 0a 20 20 20 20 69 43 65 6c 6c 20 3d  FF);.    iCell =
6130: 20 28 70 2d 3e 69 43 65 6c 6c 20 3e 3e 20 38 29   (p->iCell >> 8)
6140: 20 2d 20 31 3b 0a 0a 20 20 20 20 2f 2a 20 41 6c   - 1;..    /* Al
6150: 6c 6f 63 61 74 65 20 74 68 65 20 42 74 72 65 65  locate the Btree
6160: 43 75 72 73 6f 72 2e 61 50 67 5b 5d 20 61 72 72  Cursor.aPg[] arr
6170: 61 79 20 2a 2f 0a 20 20 20 20 61 73 73 65 72 74  ay */.    assert
6180: 28 20 70 43 73 72 2d 3e 61 50 67 3d 3d 30 20 29  ( pCsr->aPg==0 )
6190: 3b 0a 20 20 20 20 70 43 73 72 2d 3e 61 50 67 20  ;.    pCsr->aPg 
61a0: 3d 20 28 42 74 72 65 65 50 67 20 2a 29 6c 73 6d  = (BtreePg *)lsm
61b0: 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28 70 45 6e  MallocZeroRc(pEn
61c0: 76 2c 20 73 69 7a 65 6f 66 28 42 74 72 65 65 50  v, sizeof(BtreeP
61d0: 67 29 20 2a 20 6e 44 65 70 74 68 2c 20 26 72 63  g) * nDepth, &rc
61e0: 29 3b 0a 0a 20 20 20 20 2f 2a 20 50 6f 70 75 6c  );..    /* Popul
61f0: 61 74 65 20 74 68 65 20 6c 61 73 74 20 65 6e 74  ate the last ent
6200: 72 79 20 6f 66 20 74 68 65 20 61 50 67 5b 5d 20  ry of the aPg[] 
6210: 61 72 72 61 79 20 2a 2f 0a 20 20 20 20 69 66 28  array */.    if(
6220: 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20   rc==LSM_OK ){. 
6230: 20 20 20 20 20 50 61 67 65 20 2a 2a 70 70 20 3d       Page **pp =
6240: 20 26 70 43 73 72 2d 3e 61 50 67 5b 6e 44 65 70   &pCsr->aPg[nDep
6250: 74 68 2d 31 5d 2e 70 50 61 67 65 3b 0a 20 20 20  th-1].pPage;.   
6260: 20 20 20 70 43 73 72 2d 3e 69 50 67 20 3d 20 6e     pCsr->iPg = n
6270: 44 65 70 74 68 2d 31 3b 0a 20 20 20 20 20 20 70  Depth-1;.      p
6280: 43 73 72 2d 3e 6e 44 65 70 74 68 20 3d 20 6e 44  Csr->nDepth = nD
6290: 65 70 74 68 3b 0a 20 20 20 20 20 20 70 43 73 72  epth;.      pCsr
62a0: 2d 3e 61 50 67 5b 70 43 73 72 2d 3e 69 50 67 5d  ->aPg[pCsr->iPg]
62b0: 2e 69 43 65 6c 6c 20 3d 20 69 43 65 6c 6c 3b 0a  .iCell = iCell;.
62c0: 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73        rc = lsmFs
62d0: 44 62 50 61 67 65 47 65 74 28 70 43 73 72 2d 3e  DbPageGet(pCsr->
62e0: 70 46 53 2c 20 70 53 65 67 2c 20 69 4c 65 61 66  pFS, pSeg, iLeaf
62f0: 2c 20 70 70 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  , pp);.    }..  
6300: 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20 61 6e    /* Populate an
6310: 79 20 6f 74 68 65 72 20 61 50 67 5b 5d 20 61 72  y other aPg[] ar
6320: 72 61 79 20 65 6e 74 72 69 65 73 20 2a 2f 0a 20  ray entries */. 
6330: 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
6340: 4b 20 26 26 20 6e 44 65 70 74 68 3e 31 20 29 7b  K && nDepth>1 ){
6350: 0a 20 20 20 20 20 20 4c 73 6d 42 6c 6f 62 20 62  .      LsmBlob b
6360: 6c 6f 62 20 3d 20 7b 30 2c 30 2c 30 7d 3b 0a 20  lob = {0,0,0};. 
6370: 20 20 20 20 20 76 6f 69 64 20 2a 70 53 65 65 6b       void *pSeek
6380: 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 53 65 65  ;.      int nSee
6390: 6b 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 54 6f  k;.      int iTo
63a0: 70 69 63 53 65 65 6b 3b 0a 20 20 20 20 20 20 69  picSeek;.      i
63b0: 6e 74 20 69 50 67 20 3d 20 30 3b 0a 20 20 20 20  nt iPg = 0;.    
63c0: 20 20 69 6e 74 20 69 4c 6f 61 64 20 3d 20 28 69    int iLoad = (i
63d0: 6e 74 29 70 53 65 67 2d 3e 69 52 6f 6f 74 3b 0a  nt)pSeg->iRoot;.
63e0: 20 20 20 20 20 20 50 61 67 65 20 2a 70 50 67 20        Page *pPg 
63f0: 3d 20 70 43 73 72 2d 3e 61 50 67 5b 6e 44 65 70  = pCsr->aPg[nDep
6400: 74 68 2d 31 5d 2e 70 50 61 67 65 3b 0a 20 0a 20  th-1].pPage;. . 
6410: 20 20 20 20 20 69 66 28 20 70 61 67 65 4f 62 6a       if( pageObj
6420: 47 65 74 4e 52 65 63 28 70 50 67 29 3d 3d 30 20  GetNRec(pPg)==0 
6430: 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 54 68  ){.        /* Th
6440: 69 73 20 63 61 6e 20 68 61 70 70 65 6e 20 77 68  is can happen wh
6450: 65 6e 20 70 50 67 20 69 73 20 74 68 65 20 72 69  en pPg is the ri
6460: 67 68 74 2d 6d 6f 73 74 20 6c 65 61 66 20 69 6e  ght-most leaf in
6470: 20 74 68 65 20 62 2d 74 72 65 65 2e 0a 20 20 20   the b-tree..   
6480: 20 20 20 20 20 2a 2a 20 49 6e 20 74 68 69 73 20       ** In this 
6490: 63 61 73 65 2c 20 73 65 74 20 74 68 65 20 69 54  case, set the iT
64a0: 6f 70 69 63 53 65 65 6b 2f 70 53 65 65 6b 2f 6e  opicSeek/pSeek/n
64b0: 53 65 65 6b 20 6b 65 79 20 74 6f 20 61 20 76 61  Seek key to a va
64c0: 6c 75 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 67  lue.        ** g
64d0: 72 65 61 74 65 72 20 74 68 61 6e 20 61 6e 79 20  reater than any 
64e0: 72 65 61 6c 20 6b 65 79 2e 20 20 2a 2f 0a 20 20  real key.  */.  
64f0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69 43        assert( iC
6500: 65 6c 6c 3d 3d 2d 31 20 29 3b 0a 20 20 20 20 20  ell==-1 );.     
6510: 20 20 20 69 54 6f 70 69 63 53 65 65 6b 20 3d 20     iTopicSeek = 
6520: 31 30 30 30 3b 0a 20 20 20 20 20 20 20 20 70 53  1000;.        pS
6530: 65 65 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  eek = 0;.       
6540: 20 6e 53 65 65 6b 20 3d 20 30 3b 0a 20 20 20 20   nSeek = 0;.    
6550: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
6560: 20 4c 73 6d 50 67 6e 6f 20 64 75 6d 6d 79 3b 0a   LsmPgno dummy;.
6570: 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 61 67          rc = pag
6580: 65 47 65 74 42 74 72 65 65 4b 65 79 28 70 53 65  eGetBtreeKey(pSe
6590: 67 2c 20 70 50 67 2c 0a 20 20 20 20 20 20 20 20  g, pPg,.        
65a0: 20 20 20 20 30 2c 20 26 64 75 6d 6d 79 2c 20 26      0, &dummy, &
65b0: 69 54 6f 70 69 63 53 65 65 6b 2c 20 26 70 53 65  iTopicSeek, &pSe
65c0: 65 6b 2c 20 26 6e 53 65 65 6b 2c 20 26 70 43 73  ek, &nSeek, &pCs
65d0: 72 2d 3e 62 6c 6f 62 0a 20 20 20 20 20 20 20 20  r->blob.        
65e0: 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  );.      }..    
65f0: 20 20 64 6f 20 7b 0a 20 20 20 20 20 20 20 20 50    do {.        P
6600: 61 67 65 20 2a 70 50 67 32 3b 0a 20 20 20 20 20  age *pPg2;.     
6610: 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50     rc = lsmFsDbP
6620: 61 67 65 47 65 74 28 70 43 73 72 2d 3e 70 46 53  ageGet(pCsr->pFS
6630: 2c 20 70 53 65 67 2c 20 69 4c 6f 61 64 2c 20 26  , pSeg, iLoad, &
6640: 70 50 67 32 29 3b 0a 20 20 20 20 20 20 20 20 61  pPg2);.        a
6650: 73 73 65 72 74 28 20 72 63 3d 3d 4c 53 4d 5f 4f  ssert( rc==LSM_O
6660: 4b 20 7c 7c 20 70 50 67 32 3d 3d 30 20 29 3b 0a  K || pPg2==0 );.
6670: 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d          if( rc==
6680: 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  LSM_OK ){.      
6690: 20 20 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20      u8 *aData;  
66a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
66b0: 2f 2a 20 42 75 66 66 65 72 20 63 6f 6e 74 61 69  /* Buffer contai
66c0: 6e 69 6e 67 20 70 61 67 65 20 64 61 74 61 20 2a  ning page data *
66d0: 2f 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74 20  /.          int 
66e0: 6e 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20  nData;          
66f0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
6700: 6f 66 20 61 44 61 74 61 5b 5d 20 69 6e 20 62 79  of aData[] in by
6710: 74 65 73 20 2a 2f 0a 20 20 20 20 20 20 20 20 20  tes */.         
6720: 20 69 6e 74 20 69 4d 69 6e 3b 0a 20 20 20 20 20   int iMin;.     
6730: 20 20 20 20 20 69 6e 74 20 69 4d 61 78 3b 0a 20       int iMax;. 
6740: 20 20 20 20 20 20 20 20 20 69 6e 74 20 69 43 65           int iCe
6750: 6c 6c 32 3b 0a 0a 20 20 20 20 20 20 20 20 20 20  ll2;..          
6760: 61 44 61 74 61 20 3d 20 66 73 50 61 67 65 44 61  aData = fsPageDa
6770: 74 61 28 70 50 67 32 2c 20 26 6e 44 61 74 61 29  ta(pPg2, &nData)
6780: 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73 65  ;.          asse
6790: 72 74 28 20 28 70 61 67 65 47 65 74 46 6c 61 67  rt( (pageGetFlag
67a0: 73 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29 20  s(aData, nData) 
67b0: 26 20 53 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f  & SEGMENT_BTREE_
67c0: 46 4c 41 47 29 20 29 3b 0a 0a 20 20 20 20 20 20  FLAG) );..      
67d0: 20 20 20 20 69 4c 6f 61 64 20 3d 20 28 69 6e 74      iLoad = (int
67e0: 29 70 61 67 65 47 65 74 50 74 72 28 61 44 61 74  )pageGetPtr(aDat
67f0: 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 20  a, nData);.     
6800: 20 20 20 20 20 69 43 65 6c 6c 32 20 3d 20 70 61       iCell2 = pa
6810: 67 65 47 65 74 4e 52 65 63 28 61 44 61 74 61 2c  geGetNRec(aData,
6820: 20 6e 44 61 74 61 29 3b 20 0a 20 20 20 20 20 20   nData); .      
6830: 20 20 20 20 69 4d 61 78 20 3d 20 69 43 65 6c 6c      iMax = iCell
6840: 32 2d 31 3b 0a 20 20 20 20 20 20 20 20 20 20 69  2-1;.          i
6850: 4d 69 6e 20 3d 20 30 3b 0a 0a 20 20 20 20 20 20  Min = 0;..      
6860: 20 20 20 20 77 68 69 6c 65 28 20 69 4d 61 78 3e      while( iMax>
6870: 3d 69 4d 69 6e 20 29 7b 0a 20 20 20 20 20 20 20  =iMin ){.       
6880: 20 20 20 20 20 69 6e 74 20 69 54 72 79 20 3d 20       int iTry = 
6890: 28 69 4d 69 6e 2b 69 4d 61 78 29 2f 32 3b 0a 20  (iMin+iMax)/2;. 
68a0: 20 20 20 20 20 20 20 20 20 20 20 76 6f 69 64 20             void 
68b0: 2a 70 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b  *pKey; int nKey;
68c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 20           /* Key 
68d0: 66 6f 72 20 63 65 6c 6c 20 69 54 72 79 20 2a 2f  for cell iTry */
68e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74  .            int
68f0: 20 69 54 6f 70 69 63 3b 20 20 20 20 20 20 20 20   iTopic;        
6900: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f             /* To
6910: 70 69 63 20 66 6f 72 20 6b 65 79 20 70 4b 65 79  pic for key pKey
6920: 54 2f 6e 4b 65 79 54 20 2a 2f 0a 20 20 20 20 20  T/nKeyT */.     
6930: 20 20 20 20 20 20 20 4c 73 6d 50 67 6e 6f 20 69         LsmPgno i
6940: 50 74 72 3b 20 20 20 20 20 20 20 20 20 20 20 20  Ptr;            
6950: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
6960: 66 6f 72 20 63 65 6c 6c 20 69 54 72 79 20 2a 2f  for cell iTry */
6970: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74  .            int
6980: 20 72 65 73 3b 20 20 20 20 20 20 20 20 20 20 20   res;           
6990: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 28 70             /* (p
69a0: 53 65 65 6b 20 2d 20 70 4b 65 79 54 29 20 2a 2f  Seek - pKeyT) */
69b0: 0a 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63  ..            rc
69c0: 20 3d 20 70 61 67 65 47 65 74 42 74 72 65 65 4b   = pageGetBtreeK
69d0: 65 79 28 0a 20 20 20 20 20 20 20 20 20 20 20 20  ey(.            
69e0: 20 20 20 20 70 53 65 67 2c 20 70 50 67 32 2c 20      pSeg, pPg2, 
69f0: 69 54 72 79 2c 20 26 69 50 74 72 2c 20 26 69 54  iTry, &iPtr, &iT
6a00: 6f 70 69 63 2c 20 26 70 4b 65 79 2c 20 26 6e 4b  opic, &pKey, &nK
6a10: 65 79 2c 20 26 62 6c 6f 62 0a 20 20 20 20 20 20  ey, &blob.      
6a20: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20        );.       
6a30: 20 20 20 20 20 69 66 28 20 72 63 21 3d 4c 53 4d       if( rc!=LSM
6a40: 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 0a 20 20  _OK ) break;..  
6a50: 20 20 20 20 20 20 20 20 20 20 72 65 73 20 3d 20            res = 
6a60: 73 6f 72 74 65 64 4b 65 79 43 6f 6d 70 61 72 65  sortedKeyCompare
6a70: 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (.              
6a80: 20 20 78 43 6d 70 2c 20 69 54 6f 70 69 63 53 65    xCmp, iTopicSe
6a90: 65 6b 2c 20 70 53 65 65 6b 2c 20 6e 53 65 65 6b  ek, pSeek, nSeek
6aa0: 2c 20 69 54 6f 70 69 63 2c 20 70 4b 65 79 2c 20  , iTopic, pKey, 
6ab0: 6e 4b 65 79 0a 20 20 20 20 20 20 20 20 20 20 20  nKey.           
6ac0: 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20   );.            
6ad0: 61 73 73 65 72 74 28 20 72 65 73 21 3d 30 20 29  assert( res!=0 )
6ae0: 3b 0a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  ;..            i
6af0: 66 28 20 72 65 73 3c 30 20 29 7b 0a 20 20 20 20  f( res<0 ){.    
6b00: 20 20 20 20 20 20 20 20 20 20 69 4c 6f 61 64 20            iLoad 
6b10: 3d 20 28 69 6e 74 29 69 50 74 72 3b 0a 20 20 20  = (int)iPtr;.   
6b20: 20 20 20 20 20 20 20 20 20 20 20 69 43 65 6c 6c             iCell
6b30: 32 20 3d 20 69 54 72 79 3b 0a 20 20 20 20 20 20  2 = iTry;.      
6b40: 20 20 20 20 20 20 20 20 69 4d 61 78 20 3d 20 69          iMax = i
6b50: 54 72 79 2d 31 3b 0a 20 20 20 20 20 20 20 20 20  Try-1;.         
6b60: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6b70: 20 20 20 20 20 20 20 20 69 4d 69 6e 20 3d 20 69          iMin = i
6b80: 54 72 79 2b 31 3b 0a 20 20 20 20 20 20 20 20 20  Try+1;.         
6b90: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 7d     }.          }
6ba0: 0a 0a 20 20 20 20 20 20 20 20 20 20 70 43 73 72  ..          pCsr
6bb0: 2d 3e 61 50 67 5b 69 50 67 5d 2e 70 50 61 67 65  ->aPg[iPg].pPage
6bc0: 20 3d 20 70 50 67 32 3b 0a 20 20 20 20 20 20 20   = pPg2;.       
6bd0: 20 20 20 70 43 73 72 2d 3e 61 50 67 5b 69 50 67     pCsr->aPg[iPg
6be0: 5d 2e 69 43 65 6c 6c 20 3d 20 69 43 65 6c 6c 32  ].iCell = iCell2
6bf0: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 50 67 2b  ;.          iPg+
6c00: 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73  +;.          ass
6c10: 65 72 74 28 20 69 50 67 21 3d 6e 44 65 70 74 68  ert( iPg!=nDepth
6c20: 2d 31 20 0a 20 20 20 20 20 20 20 20 20 20 20 20  -1 .            
6c30: 20 20 20 7c 7c 20 6c 73 6d 46 73 52 65 64 69 72     || lsmFsRedir
6c40: 65 63 74 50 61 67 65 28 70 43 73 72 2d 3e 70 46  ectPage(pCsr->pF
6c50: 53 2c 20 70 53 65 67 2d 3e 70 52 65 64 69 72 65  S, pSeg->pRedire
6c60: 63 74 2c 20 69 4c 6f 61 64 29 3d 3d 69 4c 65 61  ct, iLoad)==iLea
6c70: 66 0a 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20  f.          );. 
6c80: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
6c90: 77 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f  while( rc==LSM_O
6ca0: 4b 20 26 26 20 69 50 67 3c 28 6e 44 65 70 74 68  K && iPg<(nDepth
6cb0: 2d 31 29 20 29 3b 0a 20 20 20 20 20 20 73 6f 72  -1) );.      sor
6cc0: 74 65 64 42 6c 6f 62 46 72 65 65 28 26 62 6c 6f  tedBlobFree(&blo
6cd0: 62 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  b);.    }..    /
6ce0: 2a 20 4c 6f 61 64 20 74 68 65 20 63 75 72 72 65  * Load the curre
6cf0: 6e 74 20 6b 65 79 20 61 6e 64 20 70 6f 69 6e 74  nt key and point
6d00: 65 72 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63  er */.    if( rc
6d10: 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20  ==LSM_OK ){.    
6d20: 20 20 42 74 72 65 65 50 67 20 2a 70 42 74 72 65    BtreePg *pBtre
6d30: 65 50 67 3b 0a 20 20 20 20 20 20 75 38 20 2a 61  ePg;.      u8 *a
6d40: 44 61 74 61 3b 0a 20 20 20 20 20 20 69 6e 74 20  Data;.      int 
6d50: 6e 44 61 74 61 3b 0a 0a 20 20 20 20 20 20 70 42  nData;..      pB
6d60: 74 72 65 65 50 67 20 3d 20 26 70 43 73 72 2d 3e  treePg = &pCsr->
6d70: 61 50 67 5b 70 43 73 72 2d 3e 69 50 67 5d 3b 0a  aPg[pCsr->iPg];.
6d80: 20 20 20 20 20 20 61 44 61 74 61 20 3d 20 66 73        aData = fs
6d90: 50 61 67 65 44 61 74 61 28 70 42 74 72 65 65 50  PageData(pBtreeP
6da0: 67 2d 3e 70 50 61 67 65 2c 20 26 6e 44 61 74 61  g->pPage, &nData
6db0: 29 3b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 69  );.      pCsr->i
6dc0: 50 74 72 20 3d 20 62 74 72 65 65 43 75 72 73 6f  Ptr = btreeCurso
6dd0: 72 50 74 72 28 61 44 61 74 61 2c 20 6e 44 61 74  rPtr(aData, nDat
6de0: 61 2c 20 70 42 74 72 65 65 50 67 2d 3e 69 43 65  a, pBtreePg->iCe
6df0: 6c 6c 2b 31 29 3b 0a 20 20 20 20 20 20 69 66 28  ll+1);.      if(
6e00: 20 70 42 74 72 65 65 50 67 2d 3e 69 43 65 6c 6c   pBtreePg->iCell
6e10: 3c 30 20 29 7b 0a 20 20 20 20 20 20 20 20 4c 73  <0 ){.        Ls
6e20: 6d 50 67 6e 6f 20 64 75 6d 6d 79 3b 0a 20 20 20  mPgno dummy;.   
6e30: 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20       int i;.    
6e40: 20 20 20 20 66 6f 72 28 69 3d 70 43 73 72 2d 3e      for(i=pCsr->
6e50: 69 50 67 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d  iPg-1; i>=0; i--
6e60: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  ){.          if(
6e70: 20 70 43 73 72 2d 3e 61 50 67 5b 69 5d 2e 69 43   pCsr->aPg[i].iC
6e80: 65 6c 6c 3e 30 20 29 20 62 72 65 61 6b 3b 0a 20  ell>0 ) break;. 
6e90: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
6ea0: 20 61 73 73 65 72 74 28 20 69 3e 3d 30 20 29 3b   assert( i>=0 );
6eb0: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 61  .        rc = pa
6ec0: 67 65 47 65 74 42 74 72 65 65 4b 65 79 28 70 53  geGetBtreeKey(pS
6ed0: 65 67 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  eg,.            
6ee0: 70 43 73 72 2d 3e 61 50 67 5b 69 5d 2e 70 50 61  pCsr->aPg[i].pPa
6ef0: 67 65 2c 20 70 43 73 72 2d 3e 61 50 67 5b 69 5d  ge, pCsr->aPg[i]
6f00: 2e 69 43 65 6c 6c 2d 31 2c 0a 20 20 20 20 20 20  .iCell-1,.      
6f10: 20 20 20 20 20 20 26 64 75 6d 6d 79 2c 20 26 70        &dummy, &p
6f20: 43 73 72 2d 3e 65 54 79 70 65 2c 20 26 70 43 73  Csr->eType, &pCs
6f30: 72 2d 3e 70 4b 65 79 2c 20 26 70 43 73 72 2d 3e  r->pKey, &pCsr->
6f40: 6e 4b 65 79 2c 20 26 70 43 73 72 2d 3e 62 6c 6f  nKey, &pCsr->blo
6f50: 62 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20  b.        );.   
6f60: 20 20 20 20 20 70 43 73 72 2d 3e 65 54 79 70 65       pCsr->eType
6f70: 20 7c 3d 20 4c 53 4d 5f 53 45 50 41 52 41 54 4f   |= LSM_SEPARATO
6f80: 52 3b 0a 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  R;..      }else{
6f90: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 62 74  .        rc = bt
6fa0: 72 65 65 43 75 72 73 6f 72 4c 6f 61 64 4b 65 79  reeCursorLoadKey
6fb0: 28 70 43 73 72 29 3b 0a 20 20 20 20 20 20 7d 0a  (pCsr);.      }.
6fc0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
6fd0: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
6fe0: 20 69 6e 74 20 62 74 72 65 65 43 75 72 73 6f 72   int btreeCursor
6ff0: 4e 65 77 28 0a 20 20 6c 73 6d 5f 64 62 20 2a 70  New(.  lsm_db *p
7000: 44 62 2c 0a 20 20 53 65 67 6d 65 6e 74 20 2a 70  Db,.  Segment *p
7010: 53 65 67 2c 0a 20 20 42 74 72 65 65 43 75 72 73  Seg,.  BtreeCurs
7020: 6f 72 20 2a 2a 70 70 43 73 72 0a 29 7b 0a 20 20  or **ppCsr.){.  
7030: 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b  int rc = LSM_OK;
7040: 0a 20 20 42 74 72 65 65 43 75 72 73 6f 72 20 2a  .  BtreeCursor *
7050: 70 43 73 72 3b 0a 20 20 0a 20 20 61 73 73 65 72  pCsr;.  .  asser
7060: 74 28 20 70 53 65 67 2d 3e 69 52 6f 6f 74 20 29  t( pSeg->iRoot )
7070: 3b 0a 20 20 70 43 73 72 20 3d 20 6c 73 6d 4d 61  ;.  pCsr = lsmMa
7080: 6c 6c 6f 63 5a 65 72 6f 52 63 28 70 44 62 2d 3e  llocZeroRc(pDb->
7090: 70 45 6e 76 2c 20 73 69 7a 65 6f 66 28 42 74 72  pEnv, sizeof(Btr
70a0: 65 65 43 75 72 73 6f 72 29 2c 20 26 72 63 29 3b  eeCursor), &rc);
70b0: 0a 20 20 69 66 28 20 70 43 73 72 20 29 7b 0a 20  .  if( pCsr ){. 
70c0: 20 20 20 70 43 73 72 2d 3e 70 46 53 20 3d 20 70     pCsr->pFS = p
70d0: 44 62 2d 3e 70 46 53 3b 0a 20 20 20 20 70 43 73  Db->pFS;.    pCs
70e0: 72 2d 3e 70 53 65 67 20 3d 20 70 53 65 67 3b 0a  r->pSeg = pSeg;.
70f0: 20 20 20 20 70 43 73 72 2d 3e 69 50 67 20 3d 20      pCsr->iPg = 
7100: 2d 31 3b 0a 20 20 7d 0a 0a 20 20 2a 70 70 43 73  -1;.  }..  *ppCs
7110: 72 20 3d 20 70 43 73 72 3b 0a 20 20 72 65 74 75  r = pCsr;.  retu
7120: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
7130: 20 76 6f 69 64 20 73 65 67 6d 65 6e 74 50 74 72   void segmentPtr
7140: 53 65 74 50 61 67 65 28 53 65 67 6d 65 6e 74 50  SetPage(SegmentP
7150: 74 72 20 2a 70 50 74 72 2c 20 50 61 67 65 20 2a  tr *pPtr, Page *
7160: 70 4e 65 78 74 29 7b 0a 20 20 6c 73 6d 46 73 50  pNext){.  lsmFsP
7170: 61 67 65 52 65 6c 65 61 73 65 28 70 50 74 72 2d  ageRelease(pPtr-
7180: 3e 70 50 67 29 3b 0a 20 20 69 66 28 20 70 4e 65  >pPg);.  if( pNe
7190: 78 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 44  xt ){.    int nD
71a0: 61 74 61 3b 0a 20 20 20 20 75 38 20 2a 61 44 61  ata;.    u8 *aDa
71b0: 74 61 20 3d 20 66 73 50 61 67 65 44 61 74 61 28  ta = fsPageData(
71c0: 70 4e 65 78 74 2c 20 26 6e 44 61 74 61 29 3b 0a  pNext, &nData);.
71d0: 20 20 20 20 70 50 74 72 2d 3e 6e 43 65 6c 6c 20      pPtr->nCell 
71e0: 3d 20 70 61 67 65 47 65 74 4e 52 65 63 28 61 44  = pageGetNRec(aD
71f0: 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20  ata, nData);.   
7200: 20 70 50 74 72 2d 3e 66 6c 61 67 73 20 3d 20 28   pPtr->flags = (
7210: 75 31 36 29 70 61 67 65 47 65 74 46 6c 61 67 73  u16)pageGetFlags
7220: 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a  (aData, nData);.
7230: 20 20 20 20 70 50 74 72 2d 3e 69 50 74 72 20 3d      pPtr->iPtr =
7240: 20 70 61 67 65 47 65 74 50 74 72 28 61 44 61 74   pageGetPtr(aDat
7250: 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 7d 0a 20  a, nData);.  }. 
7260: 20 70 50 74 72 2d 3e 70 50 67 20 3d 20 70 4e 65   pPtr->pPg = pNe
7270: 78 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 61  xt;.}../*.** Loa
7280: 64 20 61 20 6e 65 77 20 70 61 67 65 20 69 6e 74  d a new page int
7290: 6f 20 74 68 65 20 53 65 67 6d 65 6e 74 50 74 72  o the SegmentPtr
72a0: 20 6f 62 6a 65 63 74 20 70 50 74 72 2e 0a 2a 2f   object pPtr..*/
72b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 67 6d  .static int segm
72c0: 65 6e 74 50 74 72 4c 6f 61 64 50 61 67 65 28 0a  entPtrLoadPage(.
72d0: 20 20 46 69 6c 65 53 79 73 74 65 6d 20 2a 70 46    FileSystem *pF
72e0: 53 2c 0a 20 20 53 65 67 6d 65 6e 74 50 74 72 20  S,.  SegmentPtr 
72f0: 2a 70 50 74 72 2c 20 20 20 20 20 20 20 20 20 20  *pPtr,          
7300: 20 20 20 20 2f 2a 20 4c 6f 61 64 20 70 61 67 65      /* Load page
7310: 20 69 6e 74 6f 20 74 68 69 73 20 53 65 67 6d 65   into this Segme
7320: 6e 74 50 74 72 20 6f 62 6a 65 63 74 20 2a 2f 0a  ntPtr object */.
7330: 20 20 69 6e 74 20 69 4e 65 77 20 20 20 20 20 20    int iNew      
7340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7350: 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20   /* Page number 
7360: 6f 66 20 6e 65 77 20 70 61 67 65 20 2a 2f 0a 29  of new page */.)
7370: 7b 0a 20 20 50 61 67 65 20 2a 70 50 67 20 3d 20  {.  Page *pPg = 
7380: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
7390: 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 20 70 61     /* The new pa
73a0: 67 65 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20  ge */.  int rc; 
73b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
73c0: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
73d0: 20 43 6f 64 65 20 2a 2f 0a 0a 20 20 72 63 20 3d   Code */..  rc =
73e0: 20 6c 73 6d 46 73 44 62 50 61 67 65 47 65 74 28   lsmFsDbPageGet(
73f0: 70 46 53 2c 20 70 50 74 72 2d 3e 70 53 65 67 2c  pFS, pPtr->pSeg,
7400: 20 69 4e 65 77 2c 20 26 70 50 67 29 3b 0a 20 20   iNew, &pPg);.  
7410: 61 73 73 65 72 74 28 20 72 63 3d 3d 4c 53 4d 5f  assert( rc==LSM_
7420: 4f 4b 20 7c 7c 20 70 50 67 3d 3d 30 20 29 3b 0a  OK || pPg==0 );.
7430: 20 20 73 65 67 6d 65 6e 74 50 74 72 53 65 74 50    segmentPtrSetP
7440: 61 67 65 28 70 50 74 72 2c 20 70 50 67 29 3b 0a  age(pPtr, pPg);.
7450: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
7460: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 67 6d  .static int segm
7470: 65 6e 74 50 74 72 52 65 61 64 44 61 74 61 28 0a  entPtrReadData(.
7480: 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50    SegmentPtr *pP
7490: 74 72 2c 0a 20 20 69 6e 74 20 69 4f 66 66 2c 0a  tr,.  int iOff,.
74a0: 20 20 69 6e 74 20 6e 42 79 74 65 2c 0a 20 20 76    int nByte,.  v
74b0: 6f 69 64 20 2a 2a 70 70 44 61 74 61 2c 0a 20 20  oid **ppData,.  
74c0: 4c 73 6d 42 6c 6f 62 20 2a 70 42 6c 6f 62 0a 29  LsmBlob *pBlob.)
74d0: 7b 0a 20 20 72 65 74 75 72 6e 20 73 6f 72 74 65  {.  return sorte
74e0: 64 52 65 61 64 44 61 74 61 28 70 50 74 72 2d 3e  dReadData(pPtr->
74f0: 70 53 65 67 2c 20 70 50 74 72 2d 3e 70 50 67 2c  pSeg, pPtr->pPg,
7500: 20 69 4f 66 66 2c 20 6e 42 79 74 65 2c 20 70 70   iOff, nByte, pp
7510: 44 61 74 61 2c 20 70 42 6c 6f 62 29 3b 0a 7d 0a  Data, pBlob);.}.
7520: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 67 6d  .static int segm
7530: 65 6e 74 50 74 72 4e 65 78 74 50 61 67 65 28 0a  entPtrNextPage(.
7540: 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50    SegmentPtr *pP
7550: 74 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  tr,             
7560: 20 2f 2a 20 4c 6f 61 64 20 70 61 67 65 20 69 6e   /* Load page in
7570: 74 6f 20 74 68 69 73 20 53 65 67 6d 65 6e 74 50  to this SegmentP
7580: 74 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69  tr object */.  i
7590: 6e 74 20 65 44 69 72 20 20 20 20 20 20 20 20 20  nt eDir         
75a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
75b0: 20 2b 31 20 66 6f 72 20 6e 65 78 74 28 29 2c 20   +1 for next(), 
75c0: 2d 31 20 66 6f 72 20 70 72 65 76 28 29 20 2a 2f  -1 for prev() */
75d0: 0a 29 7b 0a 20 20 50 61 67 65 20 2a 70 4e 65 78  .){.  Page *pNex
75e0: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
75f0: 20 20 20 20 20 2f 2a 20 4e 65 77 20 70 61 67 65       /* New page
7600: 20 74 6f 20 6c 6f 61 64 20 2a 2f 0a 20 20 69 6e   to load */.  in
7610: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
7620: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7630: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a  Return code */..
7640: 20 20 61 73 73 65 72 74 28 20 65 44 69 72 3d 3d    assert( eDir==
7650: 31 20 7c 7c 20 65 44 69 72 3d 3d 2d 31 20 29 3b  1 || eDir==-1 );
7660: 0a 20 20 61 73 73 65 72 74 28 20 70 50 74 72 2d  .  assert( pPtr-
7670: 3e 70 50 67 20 29 3b 0a 20 20 61 73 73 65 72 74  >pPg );.  assert
7680: 28 20 70 50 74 72 2d 3e 70 53 65 67 20 7c 7c 20  ( pPtr->pSeg || 
7690: 65 44 69 72 3e 30 20 29 3b 0a 0a 20 20 72 63 20  eDir>0 );..  rc 
76a0: 3d 20 6c 73 6d 46 73 44 62 50 61 67 65 4e 65 78  = lsmFsDbPageNex
76b0: 74 28 70 50 74 72 2d 3e 70 53 65 67 2c 20 70 50  t(pPtr->pSeg, pP
76c0: 74 72 2d 3e 70 50 67 2c 20 65 44 69 72 2c 20 26  tr->pPg, eDir, &
76d0: 70 4e 65 78 74 29 3b 0a 20 20 61 73 73 65 72 74  pNext);.  assert
76e0: 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20  ( rc==LSM_OK || 
76f0: 70 4e 65 78 74 3d 3d 30 20 29 3b 0a 20 20 73 65  pNext==0 );.  se
7700: 67 6d 65 6e 74 50 74 72 53 65 74 50 61 67 65 28  gmentPtrSetPage(
7710: 70 50 74 72 2c 20 70 4e 65 78 74 29 3b 0a 20 20  pPtr, pNext);.  
7720: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
7730: 61 74 69 63 20 69 6e 74 20 73 65 67 6d 65 6e 74  atic int segment
7740: 50 74 72 4c 6f 61 64 43 65 6c 6c 28 0a 20 20 53  PtrLoadCell(.  S
7750: 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72 2c  egmentPtr *pPtr,
7760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7770: 20 4c 6f 61 64 20 70 61 67 65 20 69 6e 74 6f 20   Load page into 
7780: 74 68 69 73 20 53 65 67 6d 65 6e 74 50 74 72 20  this SegmentPtr 
7790: 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20  object */.  int 
77a0: 69 4e 65 77 20 20 20 20 20 20 20 20 20 20 20 20  iNew            
77b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 65             /* Ce
77c0: 6c 6c 20 6e 75 6d 62 65 72 20 6f 66 20 6e 65 77  ll number of new
77d0: 20 63 65 6c 6c 20 2a 2f 0a 29 7b 0a 20 20 69 6e   cell */.){.  in
77e0: 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20  t rc = LSM_OK;. 
77f0: 20 69 66 28 20 70 50 74 72 2d 3e 70 50 67 20 29   if( pPtr->pPg )
7800: 7b 0a 20 20 20 20 75 38 20 2a 61 44 61 74 61 3b  {.    u8 *aData;
7810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7820: 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
7830: 6f 20 70 61 67 65 20 64 61 74 61 20 62 75 66 66  o page data buff
7840: 65 72 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 4f  er */.    int iO
7850: 66 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ff;             
7860: 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65          /* Offse
7870: 74 20 69 6e 20 61 44 61 74 61 5b 5d 20 74 6f 20  t in aData[] to 
7880: 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20 20  read from */.   
7890: 20 69 6e 74 20 6e 50 67 73 7a 3b 20 20 20 20 20   int nPgsz;     
78a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
78b0: 2a 20 53 69 7a 65 20 6f 66 20 70 61 67 65 20 28  * Size of page (
78c0: 61 44 61 74 61 5b 5d 29 20 69 6e 20 62 79 74 65  aData[]) in byte
78d0: 73 20 2a 2f 0a 0a 20 20 20 20 61 73 73 65 72 74  s */..    assert
78e0: 28 20 69 4e 65 77 3c 70 50 74 72 2d 3e 6e 43 65  ( iNew<pPtr->nCe
78f0: 6c 6c 20 29 3b 0a 20 20 20 20 70 50 74 72 2d 3e  ll );.    pPtr->
7900: 69 43 65 6c 6c 20 3d 20 69 4e 65 77 3b 0a 20 20  iCell = iNew;.  
7910: 20 20 61 44 61 74 61 20 3d 20 66 73 50 61 67 65    aData = fsPage
7920: 44 61 74 61 28 70 50 74 72 2d 3e 70 50 67 2c 20  Data(pPtr->pPg, 
7930: 26 6e 50 67 73 7a 29 3b 0a 20 20 20 20 69 4f 66  &nPgsz);.    iOf
7940: 66 20 3d 20 6c 73 6d 47 65 74 55 31 36 28 26 61  f = lsmGetU16(&a
7950: 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f 43 45 4c  Data[SEGMENT_CEL
7960: 4c 50 54 52 5f 4f 46 46 53 45 54 28 6e 50 67 73  LPTR_OFFSET(nPgs
7970: 7a 2c 20 70 50 74 72 2d 3e 69 43 65 6c 6c 29 5d  z, pPtr->iCell)]
7980: 29 3b 0a 20 20 20 20 70 50 74 72 2d 3e 65 54 79  );.    pPtr->eTy
7990: 70 65 20 3d 20 61 44 61 74 61 5b 69 4f 66 66 5d  pe = aData[iOff]
79a0: 3b 0a 20 20 20 20 69 4f 66 66 2b 2b 3b 0a 20 20  ;.    iOff++;.  
79b0: 20 20 69 4f 66 66 20 2b 3d 20 47 45 54 56 41 52    iOff += GETVAR
79c0: 49 4e 54 36 34 28 26 61 44 61 74 61 5b 69 4f 66  INT64(&aData[iOf
79d0: 66 5d 2c 20 70 50 74 72 2d 3e 69 50 67 50 74 72  f], pPtr->iPgPtr
79e0: 29 3b 0a 20 20 20 20 69 4f 66 66 20 2b 3d 20 47  );.    iOff += G
79f0: 45 54 56 41 52 49 4e 54 33 32 28 26 61 44 61 74  ETVARINT32(&aDat
7a00: 61 5b 69 4f 66 66 5d 2c 20 70 50 74 72 2d 3e 6e  a[iOff], pPtr->n
7a10: 4b 65 79 29 3b 0a 20 20 20 20 69 66 28 20 72 74  Key);.    if( rt
7a20: 49 73 57 72 69 74 65 28 70 50 74 72 2d 3e 65 54  IsWrite(pPtr->eT
7a30: 79 70 65 29 20 29 7b 0a 20 20 20 20 20 20 69 4f  ype) ){.      iO
7a40: 66 66 20 2b 3d 20 47 45 54 56 41 52 49 4e 54 33  ff += GETVARINT3
7a50: 32 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c 20  2(&aData[iOff], 
7a60: 70 50 74 72 2d 3e 6e 56 61 6c 29 3b 0a 20 20 20  pPtr->nVal);.   
7a70: 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 70   }.    assert( p
7a80: 50 74 72 2d 3e 6e 4b 65 79 3e 3d 30 20 29 3b 0a  Ptr->nKey>=0 );.
7a90: 0a 20 20 20 20 72 63 20 3d 20 73 65 67 6d 65 6e  .    rc = segmen
7aa0: 74 50 74 72 52 65 61 64 44 61 74 61 28 0a 20 20  tPtrReadData(.  
7ab0: 20 20 20 20 20 20 70 50 74 72 2c 20 69 4f 66 66        pPtr, iOff
7ac0: 2c 20 70 50 74 72 2d 3e 6e 4b 65 79 2c 20 26 70  , pPtr->nKey, &p
7ad0: 50 74 72 2d 3e 70 4b 65 79 2c 20 26 70 50 74 72  Ptr->pKey, &pPtr
7ae0: 2d 3e 62 6c 6f 62 31 0a 20 20 20 20 29 3b 0a 20  ->blob1.    );. 
7af0: 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
7b00: 4b 20 26 26 20 72 74 49 73 57 72 69 74 65 28 70  K && rtIsWrite(p
7b10: 50 74 72 2d 3e 65 54 79 70 65 29 20 29 7b 0a 20  Ptr->eType) ){. 
7b20: 20 20 20 20 20 72 63 20 3d 20 73 65 67 6d 65 6e       rc = segmen
7b30: 74 50 74 72 52 65 61 64 44 61 74 61 28 0a 20 20  tPtrReadData(.  
7b40: 20 20 20 20 20 20 20 20 70 50 74 72 2c 20 69 4f          pPtr, iO
7b50: 66 66 2b 70 50 74 72 2d 3e 6e 4b 65 79 2c 20 70  ff+pPtr->nKey, p
7b60: 50 74 72 2d 3e 6e 56 61 6c 2c 20 26 70 50 74 72  Ptr->nVal, &pPtr
7b70: 2d 3e 70 56 61 6c 2c 20 26 70 50 74 72 2d 3e 62  ->pVal, &pPtr->b
7b80: 6c 6f 62 32 0a 20 20 20 20 20 20 29 3b 0a 20 20  lob2.      );.  
7b90: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
7ba0: 50 74 72 2d 3e 6e 56 61 6c 20 3d 20 30 3b 0a 20  Ptr->nVal = 0;. 
7bb0: 20 20 20 20 20 70 50 74 72 2d 3e 70 56 61 6c 20       pPtr->pVal 
7bc0: 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  = 0;.    }.  }..
7bd0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
7be0: 0a 73 74 61 74 69 63 20 53 65 67 6d 65 6e 74 20  .static Segment 
7bf0: 2a 73 6f 72 74 65 64 53 70 6c 69 74 6b 65 79 53  *sortedSplitkeyS
7c00: 65 67 6d 65 6e 74 28 4c 65 76 65 6c 20 2a 70 4c  egment(Level *pL
7c10: 65 76 65 6c 29 7b 0a 20 20 4d 65 72 67 65 20 2a  evel){.  Merge *
7c20: 70 4d 65 72 67 65 20 3d 20 70 4c 65 76 65 6c 2d  pMerge = pLevel-
7c30: 3e 70 4d 65 72 67 65 3b 0a 20 20 4d 65 72 67 65  >pMerge;.  Merge
7c40: 49 6e 70 75 74 20 2a 70 20 3d 20 26 70 4d 65 72  Input *p = &pMer
7c50: 67 65 2d 3e 73 70 6c 69 74 6b 65 79 3b 0a 20 20  ge->splitkey;.  
7c60: 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 3b 0a 20  Segment *pSeg;. 
7c70: 20 69 6e 74 20 69 3b 0a 0a 20 20 66 6f 72 28 69   int i;..  for(i
7c80: 3d 30 3b 20 69 3c 70 4d 65 72 67 65 2d 3e 6e 49  =0; i<pMerge->nI
7c90: 6e 70 75 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nput; i++){.    
7ca0: 69 66 28 20 70 2d 3e 69 50 67 3d 3d 70 4d 65 72  if( p->iPg==pMer
7cb0: 67 65 2d 3e 61 49 6e 70 75 74 5b 69 5d 2e 69 50  ge->aInput[i].iP
7cc0: 67 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20  g ) break;.  }. 
7cd0: 20 69 66 28 20 70 4d 65 72 67 65 2d 3e 6e 49 6e   if( pMerge->nIn
7ce0: 70 75 74 3d 3d 28 70 4c 65 76 65 6c 2d 3e 6e 52  put==(pLevel->nR
7cf0: 69 67 68 74 2b 31 29 20 26 26 20 69 3e 3d 28 70  ight+1) && i>=(p
7d00: 4d 65 72 67 65 2d 3e 6e 49 6e 70 75 74 2d 31 29  Merge->nInput-1)
7d10: 20 29 7b 0a 20 20 20 20 70 53 65 67 20 3d 20 26   ){.    pSeg = &
7d20: 70 4c 65 76 65 6c 2d 3e 70 4e 65 78 74 2d 3e 6c  pLevel->pNext->l
7d30: 68 73 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  hs;.  }else{.   
7d40: 20 70 53 65 67 20 3d 20 26 70 4c 65 76 65 6c 2d   pSeg = &pLevel-
7d50: 3e 61 52 68 73 5b 69 5d 3b 0a 20 20 7d 0a 0a 20  >aRhs[i];.  }.. 
7d60: 20 72 65 74 75 72 6e 20 70 53 65 67 3b 0a 7d 0a   return pSeg;.}.
7d70: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 6f 72  .static void sor
7d80: 74 65 64 53 70 6c 69 74 6b 65 79 28 6c 73 6d 5f  tedSplitkey(lsm_
7d90: 64 62 20 2a 70 44 62 2c 20 4c 65 76 65 6c 20 2a  db *pDb, Level *
7da0: 70 4c 65 76 65 6c 2c 20 69 6e 74 20 2a 70 52 63  pLevel, int *pRc
7db0: 29 7b 0a 20 20 53 65 67 6d 65 6e 74 20 2a 70 53  ){.  Segment *pS
7dc0: 65 67 3b 0a 20 20 50 61 67 65 20 2a 70 50 67 20  eg;.  Page *pPg 
7dd0: 3d 20 30 3b 0a 20 20 6c 73 6d 5f 65 6e 76 20 2a  = 0;.  lsm_env *
7de0: 70 45 6e 76 20 3d 20 70 44 62 2d 3e 70 45 6e 76  pEnv = pDb->pEnv
7df0: 3b 20 20 20 20 20 20 2f 2a 20 45 6e 76 69 72 6f  ;      /* Enviro
7e00: 6e 6d 65 6e 74 20 68 61 6e 64 6c 65 20 2a 2f 0a  nment handle */.
7e10: 20 20 69 6e 74 20 72 63 20 3d 20 2a 70 52 63 3b    int rc = *pRc;
7e20: 0a 20 20 4d 65 72 67 65 20 2a 70 4d 65 72 67 65  .  Merge *pMerge
7e30: 20 3d 20 70 4c 65 76 65 6c 2d 3e 70 4d 65 72 67   = pLevel->pMerg
7e40: 65 3b 0a 0a 20 20 70 53 65 67 20 3d 20 73 6f 72  e;..  pSeg = sor
7e50: 74 65 64 53 70 6c 69 74 6b 65 79 53 65 67 6d 65  tedSplitkeySegme
7e60: 6e 74 28 70 4c 65 76 65 6c 29 3b 0a 20 20 69 66  nt(pLevel);.  if
7e70: 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a  ( rc==LSM_OK ){.
7e80: 20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 44 62      rc = lsmFsDb
7e90: 50 61 67 65 47 65 74 28 70 44 62 2d 3e 70 46 53  PageGet(pDb->pFS
7ea0: 2c 20 70 53 65 67 2c 20 70 4d 65 72 67 65 2d 3e  , pSeg, pMerge->
7eb0: 73 70 6c 69 74 6b 65 79 2e 69 50 67 2c 20 26 70  splitkey.iPg, &p
7ec0: 50 67 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72  Pg);.  }.  if( r
7ed0: 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
7ee0: 20 69 6e 74 20 69 54 6f 70 69 63 3b 0a 20 20 20   int iTopic;.   
7ef0: 20 4c 73 6d 42 6c 6f 62 20 62 6c 6f 62 20 3d 20   LsmBlob blob = 
7f00: 7b 30 2c 20 30 2c 20 30 2c 20 30 7d 3b 0a 20 20  {0, 0, 0, 0};.  
7f10: 20 20 75 38 20 2a 61 44 61 74 61 3b 0a 20 20 20    u8 *aData;.   
7f20: 20 69 6e 74 20 6e 44 61 74 61 3b 0a 20 20 0a 20   int nData;.  . 
7f30: 20 20 20 61 44 61 74 61 20 3d 20 6c 73 6d 46 73     aData = lsmFs
7f40: 50 61 67 65 44 61 74 61 28 70 50 67 2c 20 26 6e  PageData(pPg, &n
7f50: 44 61 74 61 29 3b 0a 20 20 20 20 69 66 28 20 70  Data);.    if( p
7f60: 61 67 65 47 65 74 46 6c 61 67 73 28 61 44 61 74  ageGetFlags(aDat
7f70: 61 2c 20 6e 44 61 74 61 29 20 26 20 53 45 47 4d  a, nData) & SEGM
7f80: 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 20 29  ENT_BTREE_FLAG )
7f90: 7b 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70 4b  {.      void *pK
7fa0: 65 79 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4b  ey;.      int nK
7fb0: 65 79 3b 0a 20 20 20 20 20 20 4c 73 6d 50 67 6e  ey;.      LsmPgn
7fc0: 6f 20 64 75 6d 6d 79 3b 0a 20 20 20 20 20 20 72  o dummy;.      r
7fd0: 63 20 3d 20 70 61 67 65 47 65 74 42 74 72 65 65  c = pageGetBtree
7fe0: 4b 65 79 28 70 53 65 67 2c 0a 20 20 20 20 20 20  Key(pSeg,.      
7ff0: 20 20 20 20 70 50 67 2c 20 70 4d 65 72 67 65 2d      pPg, pMerge-
8000: 3e 73 70 6c 69 74 6b 65 79 2e 69 43 65 6c 6c 2c  >splitkey.iCell,
8010: 20 26 64 75 6d 6d 79 2c 20 26 69 54 6f 70 69 63   &dummy, &iTopic
8020: 2c 20 26 70 4b 65 79 2c 20 26 6e 4b 65 79 2c 20  , &pKey, &nKey, 
8030: 26 62 6c 6f 62 0a 20 20 20 20 20 20 29 3b 0a 20  &blob.      );. 
8040: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d       if( rc==LSM
8050: 5f 4f 4b 20 26 26 20 62 6c 6f 62 2e 70 44 61 74  _OK && blob.pDat
8060: 61 21 3d 70 4b 65 79 20 29 7b 0a 20 20 20 20 20  a!=pKey ){.     
8070: 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64 42 6c     rc = sortedBl
8080: 6f 62 53 65 74 28 70 45 6e 76 2c 20 26 62 6c 6f  obSet(pEnv, &blo
8090: 62 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a  b, pKey, nKey);.
80a0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73        }.    }els
80b0: 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 70 61  e{.      rc = pa
80c0: 67 65 47 65 74 4b 65 79 43 6f 70 79 28 0a 20 20  geGetKeyCopy(.  
80d0: 20 20 20 20 20 20 20 20 70 45 6e 76 2c 20 70 53          pEnv, pS
80e0: 65 67 2c 20 70 50 67 2c 20 70 4d 65 72 67 65 2d  eg, pPg, pMerge-
80f0: 3e 73 70 6c 69 74 6b 65 79 2e 69 43 65 6c 6c 2c  >splitkey.iCell,
8100: 20 26 69 54 6f 70 69 63 2c 20 26 62 6c 6f 62 0a   &iTopic, &blob.
8110: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 0a        );.    }..
8120: 20 20 20 20 70 4c 65 76 65 6c 2d 3e 69 53 70 6c      pLevel->iSpl
8130: 69 74 54 6f 70 69 63 20 3d 20 69 54 6f 70 69 63  itTopic = iTopic
8140: 3b 0a 20 20 20 20 70 4c 65 76 65 6c 2d 3e 70 53  ;.    pLevel->pS
8150: 70 6c 69 74 4b 65 79 20 3d 20 62 6c 6f 62 2e 70  plitKey = blob.p
8160: 44 61 74 61 3b 0a 20 20 20 20 70 4c 65 76 65 6c  Data;.    pLevel
8170: 2d 3e 6e 53 70 6c 69 74 4b 65 79 20 3d 20 62 6c  ->nSplitKey = bl
8180: 6f 62 2e 6e 44 61 74 61 3b 0a 20 20 20 20 6c 73  ob.nData;.    ls
8190: 6d 46 73 50 61 67 65 52 65 6c 65 61 73 65 28 70  mFsPageRelease(p
81a0: 50 67 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 52 63  Pg);.  }..  *pRc
81b0: 20 3d 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   = rc;.}../*.** 
81c0: 52 65 73 65 74 20 61 20 73 65 67 6d 65 6e 74 20  Reset a segment 
81d0: 63 75 72 73 6f 72 2e 20 41 6c 73 6f 20 66 72 65  cursor. Also fre
81e0: 65 20 69 74 73 20 62 75 66 66 65 72 73 20 69 66  e its buffers if
81f0: 20 74 68 65 79 20 61 72 65 20 6e 54 68 72 65 73   they are nThres
8200: 68 6f 6c 64 0a 2a 2a 20 62 79 74 65 73 20 6f 72  hold.** bytes or
8210: 20 6c 61 72 67 65 72 20 69 6e 20 73 69 7a 65 2e   larger in size.
8220: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
8230: 73 65 67 6d 65 6e 74 50 74 72 52 65 73 65 74 28  segmentPtrReset(
8240: 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72  SegmentPtr *pPtr
8250: 2c 20 69 6e 74 20 6e 54 68 72 65 73 68 6f 6c 64  , int nThreshold
8260: 29 7b 0a 20 20 6c 73 6d 46 73 50 61 67 65 52 65  ){.  lsmFsPageRe
8270: 6c 65 61 73 65 28 70 50 74 72 2d 3e 70 50 67 29  lease(pPtr->pPg)
8280: 3b 0a 20 20 70 50 74 72 2d 3e 70 50 67 20 3d 20  ;.  pPtr->pPg = 
8290: 30 3b 0a 20 20 70 50 74 72 2d 3e 6e 43 65 6c 6c  0;.  pPtr->nCell
82a0: 20 3d 20 30 3b 0a 20 20 70 50 74 72 2d 3e 70 4b   = 0;.  pPtr->pK
82b0: 65 79 20 3d 20 30 3b 0a 20 20 70 50 74 72 2d 3e  ey = 0;.  pPtr->
82c0: 6e 4b 65 79 20 3d 20 30 3b 0a 20 20 70 50 74 72  nKey = 0;.  pPtr
82d0: 2d 3e 70 56 61 6c 20 3d 20 30 3b 0a 20 20 70 50  ->pVal = 0;.  pP
82e0: 74 72 2d 3e 6e 56 61 6c 20 3d 20 30 3b 0a 20 20  tr->nVal = 0;.  
82f0: 70 50 74 72 2d 3e 65 54 79 70 65 20 3d 20 30 3b  pPtr->eType = 0;
8300: 0a 20 20 70 50 74 72 2d 3e 69 43 65 6c 6c 20 3d  .  pPtr->iCell =
8310: 20 30 3b 0a 20 20 69 66 28 20 70 50 74 72 2d 3e   0;.  if( pPtr->
8320: 62 6c 6f 62 31 2e 6e 41 6c 6c 6f 63 3e 3d 6e 54  blob1.nAlloc>=nT
8330: 68 72 65 73 68 6f 6c 64 20 29 20 73 6f 72 74 65  hreshold ) sorte
8340: 64 42 6c 6f 62 46 72 65 65 28 26 70 50 74 72 2d  dBlobFree(&pPtr-
8350: 3e 62 6c 6f 62 31 29 3b 0a 20 20 69 66 28 20 70  >blob1);.  if( p
8360: 50 74 72 2d 3e 62 6c 6f 62 32 2e 6e 41 6c 6c 6f  Ptr->blob2.nAllo
8370: 63 3e 3d 6e 54 68 72 65 73 68 6f 6c 64 20 29 20  c>=nThreshold ) 
8380: 73 6f 72 74 65 64 42 6c 6f 62 46 72 65 65 28 26  sortedBlobFree(&
8390: 70 50 74 72 2d 3e 62 6c 6f 62 32 29 3b 0a 7d 0a  pPtr->blob2);.}.
83a0: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 67 6d  .static int segm
83b0: 65 6e 74 50 74 72 49 67 6e 6f 72 65 53 65 70 61  entPtrIgnoreSepa
83c0: 72 61 74 6f 72 73 28 4d 75 6c 74 69 43 75 72 73  rators(MultiCurs
83d0: 6f 72 20 2a 70 43 73 72 2c 20 53 65 67 6d 65 6e  or *pCsr, Segmen
83e0: 74 50 74 72 20 2a 70 50 74 72 29 7b 0a 20 20 72  tPtr *pPtr){.  r
83f0: 65 74 75 72 6e 20 28 70 43 73 72 2d 3e 66 6c 61  eturn (pCsr->fla
8400: 67 73 20 26 20 43 55 52 53 4f 52 5f 52 45 41 44  gs & CURSOR_READ
8410: 5f 53 45 50 41 52 41 54 4f 52 53 29 3d 3d 30 0a  _SEPARATORS)==0.
8420: 20 20 20 20 20 20 7c 7c 20 28 70 50 74 72 21 3d        || (pPtr!=
8430: 26 70 43 73 72 2d 3e 61 50 74 72 5b 70 43 73 72  &pCsr->aPtr[pCsr
8440: 2d 3e 6e 50 74 72 2d 31 5d 29 3b 0a 7d 0a 0a 73  ->nPtr-1]);.}..s
8450: 74 61 74 69 63 20 69 6e 74 20 73 65 67 6d 65 6e  tatic int segmen
8460: 74 50 74 72 41 64 76 61 6e 63 65 28 0a 20 20 4d  tPtrAdvance(.  M
8470: 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72  ultiCursor *pCsr
8480: 2c 20 0a 20 20 53 65 67 6d 65 6e 74 50 74 72 20  , .  SegmentPtr 
8490: 2a 70 50 74 72 2c 0a 20 20 69 6e 74 20 62 52 65  *pPtr,.  int bRe
84a0: 76 65 72 73 65 0a 29 7b 0a 20 20 69 6e 74 20 65  verse.){.  int e
84b0: 44 69 72 20 3d 20 28 62 52 65 76 65 72 73 65 20  Dir = (bReverse 
84c0: 3f 20 2d 31 20 3a 20 31 29 3b 0a 20 20 4c 65 76  ? -1 : 1);.  Lev
84d0: 65 6c 20 2a 70 4c 76 6c 20 3d 20 70 50 74 72 2d  el *pLvl = pPtr-
84e0: 3e 70 4c 65 76 65 6c 3b 0a 20 20 64 6f 20 7b 0a  >pLevel;.  do {.
84f0: 20 20 20 20 69 6e 74 20 72 63 3b 0a 20 20 20 20      int rc;.    
8500: 69 6e 74 20 69 43 65 6c 6c 3b 20 20 20 20 20 20  int iCell;      
8510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8520: 20 4e 75 6d 62 65 72 20 6f 66 20 6e 65 77 20 63   Number of new c
8530: 65 6c 6c 20 69 6e 20 70 61 67 65 20 2a 2f 0a 20  ell in page */. 
8540: 20 20 20 69 6e 74 20 73 76 46 6c 61 67 73 20 3d     int svFlags =
8550: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
8560: 20 2f 2a 20 53 65 67 6d 65 6e 74 50 74 72 2e 65   /* SegmentPtr.e
8570: 54 79 70 65 20 62 65 66 6f 72 65 20 61 64 76 61  Type before adva
8580: 6e 63 65 20 2a 2f 0a 0a 20 20 20 20 69 43 65 6c  nce */..    iCel
8590: 6c 20 3d 20 70 50 74 72 2d 3e 69 43 65 6c 6c 20  l = pPtr->iCell 
85a0: 2b 20 65 44 69 72 3b 0a 20 20 20 20 61 73 73 65  + eDir;.    asse
85b0: 72 74 28 20 70 50 74 72 2d 3e 70 50 67 20 29 3b  rt( pPtr->pPg );
85c0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 69 43 65  .    assert( iCe
85d0: 6c 6c 3c 3d 70 50 74 72 2d 3e 6e 43 65 6c 6c 20  ll<=pPtr->nCell 
85e0: 26 26 20 69 43 65 6c 6c 3e 3d 2d 31 20 29 3b 0a  && iCell>=-1 );.
85f0: 0a 20 20 20 20 69 66 28 20 62 52 65 76 65 72 73  .    if( bRevers
8600: 65 20 26 26 20 70 50 74 72 2d 3e 70 53 65 67 21  e && pPtr->pSeg!
8610: 3d 26 70 50 74 72 2d 3e 70 4c 65 76 65 6c 2d 3e  =&pPtr->pLevel->
8620: 6c 68 73 20 29 7b 0a 20 20 20 20 20 20 73 76 46  lhs ){.      svF
8630: 6c 61 67 73 20 3d 20 70 50 74 72 2d 3e 65 54 79  lags = pPtr->eTy
8640: 70 65 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  pe;.      assert
8650: 28 20 73 76 46 6c 61 67 73 20 29 3b 0a 20 20 20  ( svFlags );.   
8660: 20 7d 0a 0a 20 20 20 20 69 66 28 20 69 43 65 6c   }..    if( iCel
8670: 6c 3e 3d 70 50 74 72 2d 3e 6e 43 65 6c 6c 20 7c  l>=pPtr->nCell |
8680: 7c 20 69 43 65 6c 6c 3c 30 20 29 7b 0a 20 20 20  | iCell<0 ){.   
8690: 20 20 20 64 6f 20 7b 0a 20 20 20 20 20 20 20 20     do {.        
86a0: 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74 72 4e  rc = segmentPtrN
86b0: 65 78 74 50 61 67 65 28 70 50 74 72 2c 20 65 44  extPage(pPtr, eD
86c0: 69 72 29 3b 20 0a 20 20 20 20 20 20 7d 77 68 69  ir); .      }whi
86d0: 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 0a  le( rc==LSM_OK .
86e0: 20 20 20 20 20 20 20 20 20 20 20 26 26 20 70 50             && pP
86f0: 74 72 2d 3e 70 50 67 20 0a 20 20 20 20 20 20 20  tr->pPg .       
8700: 20 20 20 20 26 26 20 28 70 50 74 72 2d 3e 6e 43      && (pPtr->nC
8710: 65 6c 6c 3d 3d 30 20 7c 7c 20 28 70 50 74 72 2d  ell==0 || (pPtr-
8720: 3e 66 6c 61 67 73 20 26 20 53 45 47 4d 45 4e 54  >flags & SEGMENT
8730: 5f 42 54 52 45 45 5f 46 4c 41 47 29 20 29 20 0a  _BTREE_FLAG) ) .
8740: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 69        );.      i
8750: 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20  f( rc!=LSM_OK ) 
8760: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20  return rc;.     
8770: 20 69 43 65 6c 6c 20 3d 20 62 52 65 76 65 72 73   iCell = bRevers
8780: 65 20 3f 20 28 70 50 74 72 2d 3e 6e 43 65 6c 6c  e ? (pPtr->nCell
8790: 2d 31 29 20 3a 20 30 3b 0a 20 20 20 20 7d 0a 20  -1) : 0;.    }. 
87a0: 20 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50     rc = segmentP
87b0: 74 72 4c 6f 61 64 43 65 6c 6c 28 70 50 74 72 2c  trLoadCell(pPtr,
87c0: 20 69 43 65 6c 6c 29 3b 0a 20 20 20 20 69 66 28   iCell);.    if(
87d0: 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65   rc!=LSM_OK ) re
87e0: 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20 69 66  turn rc;..    if
87f0: 28 20 73 76 46 6c 61 67 73 20 26 26 20 70 50 74  ( svFlags && pPt
8800: 72 2d 3e 70 50 67 20 29 7b 0a 20 20 20 20 20 20  r->pPg ){.      
8810: 69 6e 74 20 72 65 73 20 3d 20 73 6f 72 74 65 64  int res = sorted
8820: 4b 65 79 43 6f 6d 70 61 72 65 28 70 43 73 72 2d  KeyCompare(pCsr-
8830: 3e 70 44 62 2d 3e 78 43 6d 70 2c 0a 20 20 20 20  >pDb->xCmp,.    
8840: 20 20 20 20 20 20 72 74 54 6f 70 69 63 28 70 50        rtTopic(pP
8850: 74 72 2d 3e 65 54 79 70 65 29 2c 20 70 50 74 72  tr->eType), pPtr
8860: 2d 3e 70 4b 65 79 2c 20 70 50 74 72 2d 3e 6e 4b  ->pKey, pPtr->nK
8870: 65 79 2c 0a 20 20 20 20 20 20 20 20 20 20 70 4c  ey,.          pL
8880: 76 6c 2d 3e 69 53 70 6c 69 74 54 6f 70 69 63 2c  vl->iSplitTopic,
8890: 20 70 4c 76 6c 2d 3e 70 53 70 6c 69 74 4b 65 79   pLvl->pSplitKey
88a0: 2c 20 70 4c 76 6c 2d 3e 6e 53 70 6c 69 74 4b 65  , pLvl->nSplitKe
88b0: 79 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20  y.      );.     
88c0: 20 69 66 28 20 72 65 73 3c 30 20 29 20 73 65 67   if( res<0 ) seg
88d0: 6d 65 6e 74 50 74 72 52 65 73 65 74 28 70 50 74  mentPtrReset(pPt
88e0: 72 2c 20 4c 53 4d 5f 53 45 47 4d 45 4e 54 50 54  r, LSM_SEGMENTPT
88f0: 52 5f 46 52 45 45 5f 54 48 52 45 53 48 4f 4c 44  R_FREE_THRESHOLD
8900: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66  );.    }..    if
8910: 28 20 70 50 74 72 2d 3e 70 50 67 3d 3d 30 20 26  ( pPtr->pPg==0 &
8920: 26 20 28 73 76 46 6c 61 67 73 20 26 20 4c 53 4d  & (svFlags & LSM
8930: 5f 45 4e 44 5f 44 45 4c 45 54 45 29 20 29 7b 0a  _END_DELETE) ){.
8940: 20 20 20 20 20 20 53 65 67 6d 65 6e 74 20 2a 70        Segment *p
8950: 53 65 67 20 3d 20 70 50 74 72 2d 3e 70 53 65 67  Seg = pPtr->pSeg
8960: 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d  ;.      rc = lsm
8970: 46 73 44 62 50 61 67 65 47 65 74 28 70 43 73 72  FsDbPageGet(pCsr
8980: 2d 3e 70 44 62 2d 3e 70 46 53 2c 20 70 53 65 67  ->pDb->pFS, pSeg
8990: 2c 20 70 53 65 67 2d 3e 69 46 69 72 73 74 2c 20  , pSeg->iFirst, 
89a0: 26 70 50 74 72 2d 3e 70 50 67 29 3b 0a 20 20 20  &pPtr->pPg);.   
89b0: 20 20 20 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f     if( rc!=LSM_O
89c0: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
89d0: 20 20 20 20 20 70 50 74 72 2d 3e 65 54 79 70 65       pPtr->eType
89e0: 20 3d 20 4c 53 4d 5f 53 54 41 52 54 5f 44 45 4c   = LSM_START_DEL
89f0: 45 54 45 20 7c 20 4c 53 4d 5f 50 4f 49 4e 54 5f  ETE | LSM_POINT_
8a00: 44 45 4c 45 54 45 3b 0a 20 20 20 20 20 20 70 50  DELETE;.      pP
8a10: 74 72 2d 3e 65 54 79 70 65 20 7c 3d 20 28 70 4c  tr->eType |= (pL
8a20: 76 6c 2d 3e 69 53 70 6c 69 74 54 6f 70 69 63 20  vl->iSplitTopic 
8a30: 3f 20 4c 53 4d 5f 53 59 53 54 45 4d 4b 45 59 20  ? LSM_SYSTEMKEY 
8a40: 3a 20 30 29 3b 0a 20 20 20 20 20 20 70 50 74 72  : 0);.      pPtr
8a50: 2d 3e 70 4b 65 79 20 3d 20 70 4c 76 6c 2d 3e 70  ->pKey = pLvl->p
8a60: 53 70 6c 69 74 4b 65 79 3b 0a 20 20 20 20 20 20  SplitKey;.      
8a70: 70 50 74 72 2d 3e 6e 4b 65 79 20 3d 20 70 4c 76  pPtr->nKey = pLv
8a80: 6c 2d 3e 6e 53 70 6c 69 74 4b 65 79 3b 0a 20 20  l->nSplitKey;.  
8a90: 20 20 7d 0a 0a 20 20 7d 77 68 69 6c 65 28 20 70    }..  }while( p
8aa0: 43 73 72 20 0a 20 20 20 20 20 20 20 26 26 20 70  Csr .       && p
8ab0: 50 74 72 2d 3e 70 50 67 20 0a 20 20 20 20 20 20  Ptr->pPg .      
8ac0: 20 26 26 20 73 65 67 6d 65 6e 74 50 74 72 49 67   && segmentPtrIg
8ad0: 6e 6f 72 65 53 65 70 61 72 61 74 6f 72 73 28 70  noreSeparators(p
8ae0: 43 73 72 2c 20 70 50 74 72 29 0a 20 20 20 20 20  Csr, pPtr).     
8af0: 20 20 26 26 20 72 74 49 73 53 65 70 61 72 61 74    && rtIsSeparat
8b00: 6f 72 28 70 50 74 72 2d 3e 65 54 79 70 65 29 0a  or(pPtr->eType).
8b10: 20 20 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 4c    );..  return L
8b20: 53 4d 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63  SM_OK;.}..static
8b30: 20 76 6f 69 64 20 73 65 67 6d 65 6e 74 50 74 72   void segmentPtr
8b40: 45 6e 64 50 61 67 65 28 0a 20 20 46 69 6c 65 53  EndPage(.  FileS
8b50: 79 73 74 65 6d 20 2a 70 46 53 2c 20 0a 20 20 53  ystem *pFS, .  S
8b60: 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72 2c  egmentPtr *pPtr,
8b70: 20 0a 20 20 69 6e 74 20 62 4c 61 73 74 2c 20 0a   .  int bLast, .
8b80: 20 20 69 6e 74 20 2a 70 52 63 0a 29 7b 0a 20 20    int *pRc.){.  
8b90: 69 66 28 20 2a 70 52 63 3d 3d 4c 53 4d 5f 4f 4b  if( *pRc==LSM_OK
8ba0: 20 29 7b 0a 20 20 20 20 53 65 67 6d 65 6e 74 20   ){.    Segment 
8bb0: 2a 70 53 65 67 20 3d 20 70 50 74 72 2d 3e 70 53  *pSeg = pPtr->pS
8bc0: 65 67 3b 0a 20 20 20 20 50 61 67 65 20 2a 70 4e  eg;.    Page *pN
8bd0: 65 77 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20  ew = 0;.    if( 
8be0: 62 4c 61 73 74 20 29 7b 0a 20 20 20 20 20 20 2a  bLast ){.      *
8bf0: 70 52 63 20 3d 20 6c 73 6d 46 73 44 62 50 61 67  pRc = lsmFsDbPag
8c00: 65 4c 61 73 74 28 70 46 53 2c 20 70 53 65 67 2c  eLast(pFS, pSeg,
8c10: 20 26 70 4e 65 77 29 3b 0a 20 20 20 20 7d 65 6c   &pNew);.    }el
8c20: 73 65 7b 0a 20 20 20 20 20 20 2a 70 52 63 20 3d  se{.      *pRc =
8c30: 20 6c 73 6d 46 73 44 62 50 61 67 65 47 65 74 28   lsmFsDbPageGet(
8c40: 70 46 53 2c 20 70 53 65 67 2c 20 70 53 65 67 2d  pFS, pSeg, pSeg-
8c50: 3e 69 46 69 72 73 74 2c 20 26 70 4e 65 77 29 3b  >iFirst, &pNew);
8c60: 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 67 6d 65  .    }.    segme
8c70: 6e 74 50 74 72 53 65 74 50 61 67 65 28 70 50 74  ntPtrSetPage(pPt
8c80: 72 2c 20 70 4e 65 77 29 3b 0a 20 20 7d 0a 7d 0a  r, pNew);.  }.}.
8c90: 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20 74 6f 20 6d  ../*.** Try to m
8ca0: 6f 76 65 20 74 68 65 20 73 65 67 6d 65 6e 74 20  ove the segment 
8cb0: 70 6f 69 6e 74 65 72 20 70 61 73 73 65 64 20 61  pointer passed a
8cc0: 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67  s the second arg
8cd0: 75 6d 65 6e 74 20 73 6f 20 74 68 61 74 20 69 74  ument so that it
8ce0: 0a 2a 2a 20 70 6f 69 6e 74 73 20 61 74 20 65 69  .** points at ei
8cf0: 74 68 65 72 20 74 68 65 20 66 69 72 73 74 20 28  ther the first (
8d00: 62 4c 61 73 74 3d 3d 30 29 20 6f 72 20 6c 61 73  bLast==0) or las
8d10: 74 20 28 62 4c 61 73 74 3d 3d 31 29 20 63 65 6c  t (bLast==1) cel
8d20: 6c 20 69 6e 20 74 68 65 20 76 61 6c 69 64 0a 2a  l in the valid.*
8d30: 2a 20 72 65 67 69 6f 6e 20 6f 66 20 74 68 65 20  * region of the 
8d40: 73 65 67 6d 65 6e 74 20 64 65 66 69 6e 65 64 20  segment defined 
8d50: 62 79 20 70 50 74 72 2d 3e 69 46 69 72 73 74 20  by pPtr->iFirst 
8d60: 61 6e 64 20 70 50 74 72 2d 3e 69 4c 61 73 74 2e  and pPtr->iLast.
8d70: 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 4c 53  .**.** Return LS
8d80: 4d 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66  M_OK if successf
8d90: 75 6c 20 6f 72 20 61 6e 20 6c 73 6d 20 65 72 72  ul or an lsm err
8da0: 6f 72 20 63 6f 64 65 20 69 66 20 73 6f 6d 65 74  or code if somet
8db0: 68 69 6e 67 20 67 6f 65 73 0a 2a 2a 20 77 72 6f  hing goes.** wro
8dc0: 6e 67 20 28 49 4f 20 65 72 72 6f 72 2c 20 4f 4f  ng (IO error, OO
8dd0: 4d 20 65 74 63 2e 29 2e 0a 2a 2f 0a 73 74 61 74  M etc.)..*/.stat
8de0: 69 63 20 69 6e 74 20 73 65 67 6d 65 6e 74 50 74  ic int segmentPt
8df0: 72 45 6e 64 28 4d 75 6c 74 69 43 75 72 73 6f 72  rEnd(MultiCursor
8e00: 20 2a 70 43 73 72 2c 20 53 65 67 6d 65 6e 74 50   *pCsr, SegmentP
8e10: 74 72 20 2a 70 50 74 72 2c 20 69 6e 74 20 62 4c  tr *pPtr, int bL
8e20: 61 73 74 29 7b 0a 20 20 4c 65 76 65 6c 20 2a 70  ast){.  Level *p
8e30: 4c 76 6c 20 3d 20 70 50 74 72 2d 3e 70 4c 65 76  Lvl = pPtr->pLev
8e40: 65 6c 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c  el;.  int rc = L
8e50: 53 4d 5f 4f 4b 3b 0a 20 20 46 69 6c 65 53 79 73  SM_OK;.  FileSys
8e60: 74 65 6d 20 2a 70 46 53 20 3d 20 70 43 73 72 2d  tem *pFS = pCsr-
8e70: 3e 70 44 62 2d 3e 70 46 53 3b 0a 20 20 69 6e 74  >pDb->pFS;.  int
8e80: 20 62 49 67 6e 6f 72 65 3b 0a 0a 20 20 73 65 67   bIgnore;..  seg
8e90: 6d 65 6e 74 50 74 72 45 6e 64 50 61 67 65 28 70  mentPtrEndPage(p
8ea0: 46 53 2c 20 70 50 74 72 2c 20 62 4c 61 73 74 2c  FS, pPtr, bLast,
8eb0: 20 26 72 63 29 3b 0a 20 20 77 68 69 6c 65 28 20   &rc);.  while( 
8ec0: 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 50  rc==LSM_OK && pP
8ed0: 74 72 2d 3e 70 50 67 20 0a 20 20 20 20 20 20 26  tr->pPg .      &
8ee0: 26 20 28 70 50 74 72 2d 3e 6e 43 65 6c 6c 3d 3d  & (pPtr->nCell==
8ef0: 30 20 7c 7c 20 28 70 50 74 72 2d 3e 66 6c 61 67  0 || (pPtr->flag
8f00: 73 20 26 20 53 45 47 4d 45 4e 54 5f 42 54 52 45  s & SEGMENT_BTRE
8f10: 45 5f 46 4c 41 47 29 29 0a 20 20 29 7b 0a 20 20  E_FLAG)).  ){.  
8f20: 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74    rc = segmentPt
8f30: 72 4e 65 78 74 50 61 67 65 28 70 50 74 72 2c 20  rNextPage(pPtr, 
8f40: 28 62 4c 61 73 74 20 3f 20 2d 31 20 3a 20 31 29  (bLast ? -1 : 1)
8f50: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  );.  }..  if( rc
8f60: 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 50 74 72  ==LSM_OK && pPtr
8f70: 2d 3e 70 50 67 20 29 7b 0a 20 20 20 20 72 63 20  ->pPg ){.    rc 
8f80: 3d 20 73 65 67 6d 65 6e 74 50 74 72 4c 6f 61 64  = segmentPtrLoad
8f90: 43 65 6c 6c 28 70 50 74 72 2c 20 62 4c 61 73 74  Cell(pPtr, bLast
8fa0: 20 3f 20 28 70 50 74 72 2d 3e 6e 43 65 6c 6c 2d   ? (pPtr->nCell-
8fb0: 31 29 20 3a 20 30 29 3b 0a 20 20 20 20 69 66 28  1) : 0);.    if(
8fc0: 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 62   rc==LSM_OK && b
8fd0: 4c 61 73 74 20 26 26 20 70 50 74 72 2d 3e 70 53  Last && pPtr->pS
8fe0: 65 67 21 3d 26 70 4c 76 6c 2d 3e 6c 68 73 20 29  eg!=&pLvl->lhs )
8ff0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 65 73 20  {.      int res 
9000: 3d 20 73 6f 72 74 65 64 4b 65 79 43 6f 6d 70 61  = sortedKeyCompa
9010: 72 65 28 70 43 73 72 2d 3e 70 44 62 2d 3e 78 43  re(pCsr->pDb->xC
9020: 6d 70 2c 0a 20 20 20 20 20 20 20 20 20 20 72 74  mp,.          rt
9030: 54 6f 70 69 63 28 70 50 74 72 2d 3e 65 54 79 70  Topic(pPtr->eTyp
9040: 65 29 2c 20 70 50 74 72 2d 3e 70 4b 65 79 2c 20  e), pPtr->pKey, 
9050: 70 50 74 72 2d 3e 6e 4b 65 79 2c 0a 20 20 20 20  pPtr->nKey,.    
9060: 20 20 20 20 20 20 70 4c 76 6c 2d 3e 69 53 70 6c        pLvl->iSpl
9070: 69 74 54 6f 70 69 63 2c 20 70 4c 76 6c 2d 3e 70  itTopic, pLvl->p
9080: 53 70 6c 69 74 4b 65 79 2c 20 70 4c 76 6c 2d 3e  SplitKey, pLvl->
9090: 6e 53 70 6c 69 74 4b 65 79 0a 20 20 20 20 20 20  nSplitKey.      
90a0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 65 73  );.      if( res
90b0: 3c 30 20 29 20 73 65 67 6d 65 6e 74 50 74 72 52  <0 ) segmentPtrR
90c0: 65 73 65 74 28 70 50 74 72 2c 20 4c 53 4d 5f 53  eset(pPtr, LSM_S
90d0: 45 47 4d 45 4e 54 50 54 52 5f 46 52 45 45 5f 54  EGMENTPTR_FREE_T
90e0: 48 52 45 53 48 4f 4c 44 29 3b 0a 20 20 20 20 7d  HRESHOLD);.    }
90f0: 0a 20 20 7d 0a 20 20 0a 20 20 62 49 67 6e 6f 72  .  }.  .  bIgnor
9100: 65 20 3d 20 73 65 67 6d 65 6e 74 50 74 72 49 67  e = segmentPtrIg
9110: 6e 6f 72 65 53 65 70 61 72 61 74 6f 72 73 28 70  noreSeparators(p
9120: 43 73 72 2c 20 70 50 74 72 29 3b 0a 20 20 69 66  Csr, pPtr);.  if
9130: 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20  ( rc==LSM_OK && 
9140: 70 50 74 72 2d 3e 70 50 67 20 26 26 20 62 49 67  pPtr->pPg && bIg
9150: 6e 6f 72 65 20 26 26 20 72 74 49 73 53 65 70 61  nore && rtIsSepa
9160: 72 61 74 6f 72 28 70 50 74 72 2d 3e 65 54 79 70  rator(pPtr->eTyp
9170: 65 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  e) ){.    rc = s
9180: 65 67 6d 65 6e 74 50 74 72 41 64 76 61 6e 63 65  egmentPtrAdvance
9190: 28 70 43 73 72 2c 20 70 50 74 72 2c 20 62 4c 61  (pCsr, pPtr, bLa
91a0: 73 74 29 3b 0a 20 20 7d 0a 0a 23 69 66 20 30 0a  st);.  }..#if 0.
91b0: 20 20 69 66 28 20 62 4c 61 73 74 20 26 26 20 72    if( bLast && r
91c0: 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 50 74  c==LSM_OK && pPt
91d0: 72 2d 3e 70 50 67 0a 20 20 20 26 26 20 70 50 74  r->pPg.   && pPt
91e0: 72 2d 3e 70 53 65 67 3d 3d 26 70 4c 76 6c 2d 3e  r->pSeg==&pLvl->
91f0: 6c 68 73 20 0a 20 20 20 26 26 20 70 4c 76 6c 2d  lhs .   && pLvl-
9200: 3e 6e 52 69 67 68 74 20 26 26 20 28 70 50 74 72  >nRight && (pPtr
9210: 2d 3e 65 54 79 70 65 20 26 20 4c 53 4d 5f 53 54  ->eType & LSM_ST
9220: 41 52 54 5f 44 45 4c 45 54 45 29 0a 20 20 29 7b  ART_DELETE).  ){
9230: 0a 20 20 20 20 70 50 74 72 2d 3e 69 43 65 6c 6c  .    pPtr->iCell
9240: 2b 2b 3b 0a 20 20 20 20 70 50 74 72 2d 3e 65 54  ++;.    pPtr->eT
9250: 79 70 65 20 3d 20 4c 53 4d 5f 45 4e 44 5f 44 45  ype = LSM_END_DE
9260: 4c 45 54 45 20 7c 20 28 70 4c 76 6c 2d 3e 69 53  LETE | (pLvl->iS
9270: 70 6c 69 74 54 6f 70 69 63 29 3b 0a 20 20 20 20  plitTopic);.    
9280: 70 50 74 72 2d 3e 70 4b 65 79 20 3d 20 70 4c 76  pPtr->pKey = pLv
9290: 6c 2d 3e 70 53 70 6c 69 74 4b 65 79 3b 0a 20 20  l->pSplitKey;.  
92a0: 20 20 70 50 74 72 2d 3e 6e 4b 65 79 20 3d 20 70    pPtr->nKey = p
92b0: 4c 76 6c 2d 3e 6e 53 70 6c 69 74 4b 65 79 3b 0a  Lvl->nSplitKey;.
92c0: 20 20 20 20 70 50 74 72 2d 3e 70 56 61 6c 20 3d      pPtr->pVal =
92d0: 20 30 3b 0a 20 20 20 20 70 50 74 72 2d 3e 6e 56   0;.    pPtr->nV
92e0: 61 6c 20 3d 20 30 3b 0a 20 20 7d 0a 23 65 6e 64  al = 0;.  }.#end
92f0: 69 66 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  if..  return rc;
9300: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
9310: 73 65 67 6d 65 6e 74 50 74 72 4b 65 79 28 53 65  segmentPtrKey(Se
9320: 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72 2c 20  gmentPtr *pPtr, 
9330: 76 6f 69 64 20 2a 2a 70 70 4b 65 79 2c 20 69 6e  void **ppKey, in
9340: 74 20 2a 70 6e 4b 65 79 29 7b 0a 20 20 61 73 73  t *pnKey){.  ass
9350: 65 72 74 28 20 70 50 74 72 2d 3e 70 50 67 20 29  ert( pPtr->pPg )
9360: 3b 0a 20 20 2a 70 70 4b 65 79 20 3d 20 70 50 74  ;.  *ppKey = pPt
9370: 72 2d 3e 70 4b 65 79 3b 0a 20 20 2a 70 6e 4b 65  r->pKey;.  *pnKe
9380: 79 20 3d 20 70 50 74 72 2d 3e 6e 4b 65 79 3b 0a  y = pPtr->nKey;.
9390: 7d 0a 0a 23 69 66 20 30 20 2f 2a 20 4e 4f 54 20  }..#if 0 /* NOT 
93a0: 55 53 45 44 20 2a 2f 0a 73 74 61 74 69 63 20 63  USED */.static c
93b0: 68 61 72 20 2a 6b 65 79 54 6f 53 74 72 69 6e 67  har *keyToString
93c0: 28 6c 73 6d 5f 65 6e 76 20 2a 70 45 6e 76 2c 20  (lsm_env *pEnv, 
93d0: 76 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20  void *pKey, int 
93e0: 6e 4b 65 79 29 7b 0a 20 20 69 6e 74 20 69 3b 0a  nKey){.  int i;.
93f0: 20 20 75 38 20 2a 61 4b 65 79 20 3d 20 28 75 38    u8 *aKey = (u8
9400: 20 2a 29 70 4b 65 79 3b 0a 20 20 63 68 61 72 20   *)pKey;.  char 
9410: 2a 7a 52 65 74 20 3d 20 28 63 68 61 72 20 2a 29  *zRet = (char *)
9420: 6c 73 6d 4d 61 6c 6c 6f 63 28 70 45 6e 76 2c 20  lsmMalloc(pEnv, 
9430: 6e 4b 65 79 2b 31 29 3b 0a 0a 20 20 66 6f 72 28  nKey+1);..  for(
9440: 69 3d 30 3b 20 69 3c 6e 4b 65 79 3b 20 69 2b 2b  i=0; i<nKey; i++
9450: 29 7b 0a 20 20 20 20 7a 52 65 74 5b 69 5d 20 3d  ){.    zRet[i] =
9460: 20 28 63 68 61 72 29 28 69 73 61 6c 6e 75 6d 28   (char)(isalnum(
9470: 61 4b 65 79 5b 69 5d 29 20 3f 20 61 4b 65 79 5b  aKey[i]) ? aKey[
9480: 69 5d 20 3a 20 27 2e 27 29 3b 0a 20 20 7d 0a 20  i] : '.');.  }. 
9490: 20 7a 52 65 74 5b 6e 4b 65 79 5d 20 3d 20 27 5c   zRet[nKey] = '\
94a0: 30 27 3b 0a 20 20 72 65 74 75 72 6e 20 7a 52 65  0';.  return zRe
94b0: 74 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 23 69 66  t;.}.#endif..#if
94c0: 20 30 20 2f 2a 20 4e 4f 54 20 55 53 45 44 20 2a   0 /* NOT USED *
94d0: 2f 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68  /./*.** Check th
94e0: 61 74 20 74 68 65 20 70 61 67 65 20 74 68 61 74  at the page that
94f0: 20 70 50 74 72 20 63 75 72 72 65 6e 74 6c 79 20   pPtr currently 
9500: 68 61 73 20 6c 6f 61 64 65 64 20 69 73 20 74 68  has loaded is th
9510: 65 20 63 6f 72 72 65 63 74 20 70 61 67 65 0a 2a  e correct page.*
9520: 2a 20 74 6f 20 73 65 61 72 63 68 20 66 6f 72 20  * to search for 
9530: 6b 65 79 20 28 70 4b 65 79 2f 6e 4b 65 79 29 2e  key (pKey/nKey).
9540: 20 49 66 20 69 74 20 69 73 2c 20 72 65 74 75 72   If it is, retur
9550: 6e 20 31 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  n 1. Otherwise, 
9560: 61 6e 20 61 73 73 65 72 74 0a 2a 2a 20 66 61 69  an assert.** fai
9570: 6c 73 20 61 6e 64 20 74 68 69 73 20 66 75 6e 63  ls and this func
9580: 74 69 6f 6e 20 64 6f 65 73 20 6e 6f 74 20 72 65  tion does not re
9590: 74 75 72 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  turn..*/.static 
95a0: 69 6e 74 20 61 73 73 65 72 74 4b 65 79 4c 6f 63  int assertKeyLoc
95b0: 61 74 69 6f 6e 28 0a 20 20 4d 75 6c 74 69 43 75  ation(.  MultiCu
95c0: 72 73 6f 72 20 2a 70 43 73 72 2c 20 0a 20 20 53  rsor *pCsr, .  S
95d0: 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72 2c  egmentPtr *pPtr,
95e0: 20 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 2c 20   .  void *pKey, 
95f0: 69 6e 74 20 6e 4b 65 79 0a 29 7b 0a 20 20 6c 73  int nKey.){.  ls
9600: 6d 5f 65 6e 76 20 2a 70 45 6e 76 20 3d 20 6c 73  m_env *pEnv = ls
9610: 6d 46 73 45 6e 76 28 70 43 73 72 2d 3e 70 44 62  mFsEnv(pCsr->pDb
9620: 2d 3e 70 46 53 29 3b 0a 20 20 4c 73 6d 42 6c 6f  ->pFS);.  LsmBlo
9630: 62 20 62 6c 6f 62 20 3d 20 7b 30 2c 20 30 2c 20  b blob = {0, 0, 
9640: 30 7d 3b 0a 20 20 69 6e 74 20 65 44 69 72 3b 0a  0};.  int eDir;.
9650: 20 20 69 6e 74 20 69 54 6f 70 69 63 20 3d 20 30    int iTopic = 0
9660: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
9670: 20 20 2f 2a 20 54 4f 44 4f 3a 20 46 69 78 20 6d    /* TODO: Fix m
9680: 65 20 2a 2f 0a 0a 20 20 66 6f 72 28 65 44 69 72  e */..  for(eDir
9690: 3d 2d 31 3b 20 65 44 69 72 3c 3d 31 3b 20 65 44  =-1; eDir<=1; eD
96a0: 69 72 2b 3d 32 29 7b 0a 20 20 20 20 50 61 67 65  ir+=2){.    Page
96b0: 20 2a 70 54 65 73 74 20 3d 20 70 50 74 72 2d 3e   *pTest = pPtr->
96c0: 70 50 67 3b 0a 0a 20 20 20 20 6c 73 6d 46 73 50  pPg;..    lsmFsP
96d0: 61 67 65 52 65 66 28 70 54 65 73 74 29 3b 0a 20  ageRef(pTest);. 
96e0: 20 20 20 77 68 69 6c 65 28 20 70 54 65 73 74 20     while( pTest 
96f0: 29 7b 0a 20 20 20 20 20 20 53 65 67 6d 65 6e 74  ){.      Segment
9700: 20 2a 70 53 65 67 20 3d 20 70 50 74 72 2d 3e 70   *pSeg = pPtr->p
9710: 53 65 67 3b 0a 20 20 20 20 20 20 50 61 67 65 20  Seg;.      Page 
9720: 2a 70 4e 65 78 74 3b 0a 0a 20 20 20 20 20 20 69  *pNext;..      i
9730: 6e 74 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50  nt rc = lsmFsDbP
9740: 61 67 65 4e 65 78 74 28 70 53 65 67 2c 20 70 54  ageNext(pSeg, pT
9750: 65 73 74 2c 20 65 44 69 72 2c 20 26 70 4e 65 78  est, eDir, &pNex
9760: 74 29 3b 0a 20 20 20 20 20 20 6c 73 6d 46 73 50  t);.      lsmFsP
9770: 61 67 65 52 65 6c 65 61 73 65 28 70 54 65 73 74  ageRelease(pTest
9780: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 20  );.      if( rc 
9790: 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20  ) return 1;.    
97a0: 20 20 70 54 65 73 74 20 3d 20 70 4e 65 78 74 3b    pTest = pNext;
97b0: 0a 0a 20 20 20 20 20 20 69 66 28 20 70 54 65 73  ..      if( pTes
97c0: 74 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74  t ){.        int
97d0: 20 6e 44 61 74 61 3b 0a 20 20 20 20 20 20 20 20   nData;.        
97e0: 75 38 20 2a 61 44 61 74 61 20 3d 20 66 73 50 61  u8 *aData = fsPa
97f0: 67 65 44 61 74 61 28 70 54 65 73 74 2c 20 26 6e  geData(pTest, &n
9800: 44 61 74 61 29 3b 0a 20 20 20 20 20 20 20 20 69  Data);.        i
9810: 6e 74 20 6e 43 65 6c 6c 20 3d 20 70 61 67 65 47  nt nCell = pageG
9820: 65 74 4e 52 65 63 28 61 44 61 74 61 2c 20 6e 44  etNRec(aData, nD
9830: 61 74 61 29 3b 0a 20 20 20 20 20 20 20 20 69 6e  ata);.        in
9840: 74 20 66 6c 61 67 73 20 3d 20 70 61 67 65 47 65  t flags = pageGe
9850: 74 46 6c 61 67 73 28 61 44 61 74 61 2c 20 6e 44  tFlags(aData, nD
9860: 61 74 61 29 3b 0a 20 20 20 20 20 20 20 20 69 66  ata);.        if
9870: 28 20 6e 43 65 6c 6c 20 26 26 20 30 3d 3d 28 66  ( nCell && 0==(f
9880: 6c 61 67 73 26 53 45 47 4d 45 4e 54 5f 42 54 52  lags&SEGMENT_BTR
9890: 45 45 5f 46 4c 41 47 29 20 29 7b 0a 20 20 20 20  EE_FLAG) ){.    
98a0: 20 20 20 20 20 20 69 6e 74 20 6e 50 67 4b 65 79        int nPgKey
98b0: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74 20  ;.          int 
98c0: 69 50 67 54 6f 70 69 63 3b 0a 20 20 20 20 20 20  iPgTopic;.      
98d0: 20 20 20 20 75 38 20 2a 70 50 67 4b 65 79 3b 0a      u8 *pPgKey;.
98e0: 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 72 65            int re
98f0: 73 3b 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74  s;.          int
9900: 20 69 43 65 6c 6c 3b 0a 0a 20 20 20 20 20 20 20   iCell;..       
9910: 20 20 20 69 43 65 6c 6c 20 3d 20 28 28 65 44 69     iCell = ((eDi
9920: 72 20 3c 20 30 29 20 3f 20 28 6e 43 65 6c 6c 2d  r < 0) ? (nCell-
9930: 31 29 20 3a 20 30 29 3b 0a 20 20 20 20 20 20 20  1) : 0);.       
9940: 20 20 20 70 50 67 4b 65 79 20 3d 20 70 61 67 65     pPgKey = page
9950: 47 65 74 4b 65 79 28 70 53 65 67 2c 20 70 54 65  GetKey(pSeg, pTe
9960: 73 74 2c 20 69 43 65 6c 6c 2c 20 26 69 50 67 54  st, iCell, &iPgT
9970: 6f 70 69 63 2c 20 26 6e 50 67 4b 65 79 2c 20 26  opic, &nPgKey, &
9980: 62 6c 6f 62 29 3b 0a 20 20 20 20 20 20 20 20 20  blob);.         
9990: 20 72 65 73 20 3d 20 69 54 6f 70 69 63 20 2d 20   res = iTopic - 
99a0: 69 50 67 54 6f 70 69 63 3b 0a 20 20 20 20 20 20  iPgTopic;.      
99b0: 20 20 20 20 69 66 28 20 72 65 73 3d 3d 30 20 29      if( res==0 )
99c0: 20 72 65 73 20 3d 20 70 43 73 72 2d 3e 70 44 62   res = pCsr->pDb
99d0: 2d 3e 78 43 6d 70 28 70 4b 65 79 2c 20 6e 4b 65  ->xCmp(pKey, nKe
99e0: 79 2c 20 70 50 67 4b 65 79 2c 20 6e 50 67 4b 65  y, pPgKey, nPgKe
99f0: 79 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66  y);.          if
9a00: 28 20 28 65 44 69 72 3d 3d 31 20 26 26 20 72 65  ( (eDir==1 && re
9a10: 73 3e 30 29 20 7c 7c 20 28 65 44 69 72 3d 3d 2d  s>0) || (eDir==-
9a20: 31 20 26 26 20 72 65 73 3c 30 29 20 29 7b 0a 20  1 && res<0) ){. 
9a30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 61             /* Ta
9a40: 6b 69 6e 67 20 74 68 69 73 20 62 72 61 6e 63 68  king this branch
9a50: 20 6d 65 61 6e 73 20 73 6f 6d 65 74 68 69 6e 67   means something
9a60: 20 68 61 73 20 67 6f 6e 65 20 77 72 6f 6e 67 2e   has gone wrong.
9a70: 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 20 20   */.            
9a80: 63 68 61 72 20 2a 7a 4d 73 67 20 3d 20 6c 73 6d  char *zMsg = lsm
9a90: 4d 61 6c 6c 6f 63 50 72 69 6e 74 66 28 70 45 6e  MallocPrintf(pEn
9aa0: 76 2c 20 22 4b 65 79 20 5c 22 25 73 5c 22 20 69  v, "Key \"%s\" i
9ab0: 73 20 6e 6f 74 20 6f 6e 20 70 61 67 65 20 25 64  s not on page %d
9ac0: 22 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20  ", .            
9ad0: 20 20 20 20 6b 65 79 54 6f 53 74 72 69 6e 67 28      keyToString(
9ae0: 70 45 6e 76 2c 20 70 4b 65 79 2c 20 6e 4b 65 79  pEnv, pKey, nKey
9af0: 29 2c 20 6c 73 6d 46 73 50 61 67 65 4e 75 6d 62  ), lsmFsPageNumb
9b00: 65 72 28 70 50 74 72 2d 3e 70 50 67 29 0a 20 20  er(pPtr->pPg).  
9b10: 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20            );.   
9b20: 20 20 20 20 20 20 20 20 20 66 70 72 69 6e 74 66           fprintf
9b30: 28 73 74 64 65 72 72 2c 20 22 25 73 5c 6e 22 2c  (stderr, "%s\n",
9b40: 20 7a 4d 73 67 29 3b 0a 20 20 20 20 20 20 20 20   zMsg);.        
9b50: 20 20 20 20 61 73 73 65 72 74 28 20 21 22 61 73      assert( !"as
9b60: 73 65 72 74 4b 65 79 4c 6f 63 61 74 69 6f 6e 28  sertKeyLocation(
9b70: 29 20 66 61 69 6c 65 64 22 20 29 3b 0a 20 20 20  ) failed" );.   
9b80: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
9b90: 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65     lsmFsPageRele
9ba0: 61 73 65 28 70 54 65 73 74 29 3b 0a 20 20 20 20  ase(pTest);.    
9bb0: 20 20 20 20 20 20 70 54 65 73 74 20 3d 20 30 3b        pTest = 0;
9bc0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
9bd0: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
9be0: 73 6f 72 74 65 64 42 6c 6f 62 46 72 65 65 28 26  sortedBlobFree(&
9bf0: 62 6c 6f 62 29 3b 0a 20 20 72 65 74 75 72 6e 20  blob);.  return 
9c00: 31 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 23 69 66  1;.}.#endif..#if
9c10: 6e 64 65 66 20 4e 44 45 42 55 47 0a 73 74 61 74  ndef NDEBUG.stat
9c20: 69 63 20 69 6e 74 20 61 73 73 65 72 74 53 65 65  ic int assertSee
9c30: 6b 52 65 73 75 6c 74 28 0a 20 20 4d 75 6c 74 69  kResult(.  Multi
9c40: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 0a 20 20  Cursor *pCsr,.  
9c50: 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72  SegmentPtr *pPtr
9c60: 2c 0a 20 20 69 6e 74 20 69 54 6f 70 69 63 2c 0a  ,.  int iTopic,.
9c70: 20 20 76 6f 69 64 20 2a 70 4b 65 79 2c 0a 20 20    void *pKey,.  
9c80: 69 6e 74 20 6e 4b 65 79 2c 0a 20 20 69 6e 74 20  int nKey,.  int 
9c90: 65 53 65 65 6b 0a 29 7b 0a 20 20 69 66 28 20 70  eSeek.){.  if( p
9ca0: 50 74 72 2d 3e 70 50 67 20 29 7b 0a 20 20 20 20  Ptr->pPg ){.    
9cb0: 69 6e 74 20 72 65 73 3b 0a 20 20 20 20 72 65 73  int res;.    res
9cc0: 20 3d 20 73 6f 72 74 65 64 4b 65 79 43 6f 6d 70   = sortedKeyComp
9cd0: 61 72 65 28 70 43 73 72 2d 3e 70 44 62 2d 3e 78  are(pCsr->pDb->x
9ce0: 43 6d 70 2c 20 69 54 6f 70 69 63 2c 20 70 4b 65  Cmp, iTopic, pKe
9cf0: 79 2c 20 6e 4b 65 79 2c 0a 20 20 20 20 20 20 20  y, nKey,.       
9d00: 20 72 74 54 6f 70 69 63 28 70 50 74 72 2d 3e 65   rtTopic(pPtr->e
9d10: 54 79 70 65 29 2c 20 70 50 74 72 2d 3e 70 4b 65  Type), pPtr->pKe
9d20: 79 2c 20 70 50 74 72 2d 3e 6e 4b 65 79 0a 20 20  y, pPtr->nKey.  
9d30: 20 20 29 3b 0a 0a 20 20 20 20 69 66 28 20 65 53    );..    if( eS
9d40: 65 65 6b 3d 3d 4c 53 4d 5f 53 45 45 4b 5f 45 51  eek==LSM_SEEK_EQ
9d50: 20 29 20 72 65 74 75 72 6e 20 28 72 65 73 3d 3d   ) return (res==
9d60: 30 29 3b 0a 20 20 20 20 69 66 28 20 65 53 65 65  0);.    if( eSee
9d70: 6b 3d 3d 4c 53 4d 5f 53 45 45 4b 5f 4c 45 20 29  k==LSM_SEEK_LE )
9d80: 20 72 65 74 75 72 6e 20 28 72 65 73 3e 3d 30 29   return (res>=0)
9d90: 3b 0a 20 20 20 20 69 66 28 20 65 53 65 65 6b 3d  ;.    if( eSeek=
9da0: 3d 4c 53 4d 5f 53 45 45 4b 5f 47 45 20 29 20 72  =LSM_SEEK_GE ) r
9db0: 65 74 75 72 6e 20 28 72 65 73 3c 3d 30 29 3b 0a  eturn (res<=0);.
9dc0: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 31 3b    }..  return 1;
9dd0: 0a 7d 0a 23 65 6e 64 69 66 0a 0a 73 74 61 74 69  .}.#endif..stati
9de0: 63 20 69 6e 74 20 73 65 67 6d 65 6e 74 50 74 72  c int segmentPtr
9df0: 53 65 61 72 63 68 4f 76 65 72 73 69 7a 65 64 28  SearchOversized(
9e00: 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a  .  MultiCursor *
9e10: 70 43 73 72 2c 20 20 20 20 20 20 20 20 20 20 20  pCsr,           
9e20: 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 63 6f 6e     /* Cursor con
9e30: 74 65 78 74 20 2a 2f 0a 20 20 53 65 67 6d 65 6e  text */.  Segmen
9e40: 74 50 74 72 20 2a 70 50 74 72 2c 20 20 20 20 20  tPtr *pPtr,     
9e50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
9e60: 6e 74 65 72 20 74 6f 20 73 65 65 6b 20 2a 2f 0a  nter to seek */.
9e70: 20 20 69 6e 74 20 69 54 6f 70 69 63 2c 20 20 20    int iTopic,   
9e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9e90: 20 20 2f 2a 20 54 6f 70 69 63 20 6f 66 20 6b 65    /* Topic of ke
9ea0: 79 20 74 6f 20 73 65 61 72 63 68 20 66 6f 72 20  y to search for 
9eb0: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 2c  */.  void *pKey,
9ec0: 20 69 6e 74 20 6e 4b 65 79 20 20 20 20 20 20 20   int nKey       
9ed0: 20 20 20 20 20 2f 2a 20 4b 65 79 20 74 6f 20 73       /* Key to s
9ee0: 65 65 6b 20 74 6f 20 2a 2f 0a 29 7b 0a 20 20 69  eek to */.){.  i
9ef0: 6e 74 20 28 2a 78 43 6d 70 29 28 76 6f 69 64 20  nt (*xCmp)(void 
9f00: 2a 2c 20 69 6e 74 2c 20 76 6f 69 64 20 2a 2c 20  *, int, void *, 
9f10: 69 6e 74 29 20 3d 20 70 43 73 72 2d 3e 70 44 62  int) = pCsr->pDb
9f20: 2d 3e 78 43 6d 70 3b 0a 20 20 69 6e 74 20 72 63  ->xCmp;.  int rc
9f30: 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20 20 2f 2a   = LSM_OK;..  /*
9f40: 20 49 66 20 74 68 65 20 4f 56 45 52 53 49 5a 45   If the OVERSIZE
9f50: 44 20 66 6c 61 67 20 69 73 20 73 65 74 2c 20 74  D flag is set, t
9f60: 68 65 6e 20 74 68 65 72 65 20 69 73 20 6e 6f 20  hen there is no 
9f70: 70 6f 69 6e 74 65 72 20 69 6e 20 74 68 65 0a 20  pointer in the. 
9f80: 20 2a 2a 20 75 70 70 65 72 20 6c 65 76 65 6c 20   ** upper level 
9f90: 74 6f 20 74 68 65 20 6e 65 78 74 20 70 61 67 65  to the next page
9fa0: 20 69 6e 20 74 68 65 20 73 65 67 6d 65 6e 74 20   in the segment 
9fb0: 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 61 74  that contains at
9fc0: 20 6c 65 61 73 74 0a 20 20 2a 2a 20 6f 6e 65 20   least.  ** one 
9fd0: 6b 65 79 2e 20 53 6f 20 63 6f 6d 70 61 72 65 20  key. So compare 
9fe0: 74 68 65 20 6c 61 72 67 65 73 74 20 6b 65 79 20  the largest key 
9ff0: 6f 6e 20 74 68 65 20 63 75 72 72 65 6e 74 20 70  on the current p
a000: 61 67 65 20 77 69 74 68 20 74 68 65 0a 20 20 2a  age with the.  *
a010: 2a 20 6b 65 79 20 62 65 69 6e 67 20 73 6f 75 67  * key being soug
a020: 68 74 20 28 70 4b 65 79 2f 6e 4b 65 79 29 2e 20  ht (pKey/nKey). 
a030: 49 66 20 28 70 4b 65 79 2f 6e 4b 65 79 29 20 69  If (pKey/nKey) i
a040: 73 20 6c 61 72 67 65 72 2c 20 61 64 76 61 6e 63  s larger, advanc
a050: 65 0a 20 20 2a 2a 20 74 6f 20 74 68 65 20 6e 65  e.  ** to the ne
a060: 78 74 20 70 61 67 65 20 69 6e 20 74 68 65 20 73  xt page in the s
a070: 65 67 6d 65 6e 74 20 74 68 61 74 20 63 6f 6e 74  egment that cont
a080: 61 69 6e 73 20 61 74 20 6c 65 61 73 74 20 6f 6e  ains at least on
a090: 65 20 6b 65 79 2e 20 0a 20 20 2a 2f 0a 20 20 77  e key. .  */.  w
a0a0: 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b  hile( rc==LSM_OK
a0b0: 20 26 26 20 28 70 50 74 72 2d 3e 66 6c 61 67 73   && (pPtr->flags
a0c0: 20 26 20 50 47 46 54 52 5f 53 4b 49 50 5f 4e 45   & PGFTR_SKIP_NE
a0d0: 58 54 5f 46 4c 41 47 29 20 29 7b 0a 20 20 20 20  XT_FLAG) ){.    
a0e0: 75 38 20 2a 70 4c 61 73 74 4b 65 79 3b 0a 20 20  u8 *pLastKey;.  
a0f0: 20 20 69 6e 74 20 6e 4c 61 73 74 4b 65 79 3b 0a    int nLastKey;.
a100: 20 20 20 20 69 6e 74 20 69 4c 61 73 74 54 6f 70      int iLastTop
a110: 69 63 3b 0a 20 20 20 20 69 6e 74 20 72 65 73 3b  ic;.    int res;
a120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a130: 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20        /* Result 
a140: 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 2a 2f  of comparison */
a150: 0a 20 20 20 20 50 61 67 65 20 2a 70 4e 65 78 74  .    Page *pNext
a160: 3b 0a 0a 20 20 20 20 2f 2a 20 4c 6f 61 64 20 74  ;..    /* Load t
a170: 68 65 20 6c 61 73 74 20 6b 65 79 20 6f 6e 20 74  he last key on t
a180: 68 65 20 63 75 72 72 65 6e 74 20 70 61 67 65 2e  he current page.
a190: 20 2a 2f 0a 20 20 20 20 70 4c 61 73 74 4b 65 79   */.    pLastKey
a1a0: 20 3d 20 70 61 67 65 47 65 74 4b 65 79 28 70 50   = pageGetKey(pP
a1b0: 74 72 2d 3e 70 53 65 67 2c 0a 20 20 20 20 20 20  tr->pSeg,.      
a1c0: 20 20 70 50 74 72 2d 3e 70 50 67 2c 20 70 50 74    pPtr->pPg, pPt
a1d0: 72 2d 3e 6e 43 65 6c 6c 2d 31 2c 20 26 69 4c 61  r->nCell-1, &iLa
a1e0: 73 74 54 6f 70 69 63 2c 20 26 6e 4c 61 73 74 4b  stTopic, &nLastK
a1f0: 65 79 2c 20 26 70 50 74 72 2d 3e 62 6c 6f 62 31  ey, &pPtr->blob1
a200: 0a 20 20 20 20 29 3b 0a 0a 20 20 20 20 2f 2a 20  .    );..    /* 
a210: 49 66 20 74 68 65 20 6c 6f 61 64 65 64 20 6b 65  If the loaded ke
a220: 79 20 69 73 20 3e 3d 20 74 68 61 6e 20 28 70 4b  y is >= than (pK
a230: 65 79 2f 6e 4b 65 79 29 2c 20 62 72 65 61 6b 20  ey/nKey), break 
a240: 6f 75 74 20 6f 66 20 74 68 65 20 6c 6f 6f 70 2e  out of the loop.
a250: 0a 20 20 20 20 2a 2a 20 49 66 20 28 70 4b 65 79  .    ** If (pKey
a260: 2f 6e 4b 65 79 29 20 69 73 20 70 72 65 73 65 6e  /nKey) is presen
a270: 74 20 69 6e 20 74 68 69 73 20 61 72 72 61 79 2c  t in this array,
a280: 20 69 74 20 6d 75 73 74 20 62 65 20 6f 6e 20 74   it must be on t
a290: 68 65 20 63 75 72 72 65 6e 74 20 0a 20 20 20 20  he current .    
a2a0: 2a 2a 20 70 61 67 65 2e 20 20 2a 2f 0a 20 20 20  ** page.  */.   
a2b0: 20 72 65 73 20 3d 20 73 6f 72 74 65 64 4b 65 79   res = sortedKey
a2c0: 43 6f 6d 70 61 72 65 28 0a 20 20 20 20 20 20 20  Compare(.       
a2d0: 20 78 43 6d 70 2c 20 69 4c 61 73 74 54 6f 70 69   xCmp, iLastTopi
a2e0: 63 2c 20 70 4c 61 73 74 4b 65 79 2c 20 6e 4c 61  c, pLastKey, nLa
a2f0: 73 74 4b 65 79 2c 20 69 54 6f 70 69 63 2c 20 70  stKey, iTopic, p
a300: 4b 65 79 2c 20 6e 4b 65 79 0a 20 20 20 20 29 3b  Key, nKey.    );
a310: 0a 20 20 20 20 69 66 28 20 72 65 73 3e 3d 30 20  .    if( res>=0 
a320: 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 2f 2a  ) break;..    /*
a330: 20 41 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20   Advance to the 
a340: 6e 65 78 74 20 70 61 67 65 20 74 68 61 74 20 63  next page that c
a350: 6f 6e 74 61 69 6e 73 20 61 74 20 6c 65 61 73 74  ontains at least
a360: 20 6f 6e 65 20 6b 65 79 2e 20 2a 2f 0a 20 20 20   one key. */.   
a370: 20 70 4e 65 78 74 20 3d 20 70 50 74 72 2d 3e 70   pNext = pPtr->p
a380: 50 67 3b 0a 20 20 20 20 6c 73 6d 46 73 50 61 67  Pg;.    lsmFsPag
a390: 65 52 65 66 28 70 4e 65 78 74 29 3b 0a 20 20 20  eRef(pNext);.   
a3a0: 20 77 68 69 6c 65 28 20 31 20 29 7b 0a 20 20 20   while( 1 ){.   
a3b0: 20 20 20 50 61 67 65 20 2a 70 4c 6f 61 64 3b 0a     Page *pLoad;.
a3c0: 20 20 20 20 20 20 75 38 20 2a 61 44 61 74 61 3b        u8 *aData;
a3d0: 20 69 6e 74 20 6e 44 61 74 61 3b 0a 0a 20 20 20   int nData;..   
a3e0: 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50     rc = lsmFsDbP
a3f0: 61 67 65 4e 65 78 74 28 70 50 74 72 2d 3e 70 53  ageNext(pPtr->pS
a400: 65 67 2c 20 70 4e 65 78 74 2c 20 31 2c 20 26 70  eg, pNext, 1, &p
a410: 4c 6f 61 64 29 3b 0a 20 20 20 20 20 20 6c 73 6d  Load);.      lsm
a420: 46 73 50 61 67 65 52 65 6c 65 61 73 65 28 70 4e  FsPageRelease(pN
a430: 65 78 74 29 3b 0a 20 20 20 20 20 20 70 4e 65 78  ext);.      pNex
a440: 74 20 3d 20 70 4c 6f 61 64 3b 0a 20 20 20 20 20  t = pLoad;.     
a450: 20 69 66 28 20 70 4e 65 78 74 3d 3d 30 20 29 20   if( pNext==0 ) 
a460: 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 61 73  break;..      as
a470: 73 65 72 74 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b  sert( rc==LSM_OK
a480: 20 29 3b 0a 20 20 20 20 20 20 61 44 61 74 61 20   );.      aData 
a490: 3d 20 6c 73 6d 46 73 50 61 67 65 44 61 74 61 28  = lsmFsPageData(
a4a0: 70 4e 65 78 74 2c 20 26 6e 44 61 74 61 29 3b 0a  pNext, &nData);.
a4b0: 20 20 20 20 20 20 69 66 28 20 28 70 61 67 65 47        if( (pageG
a4c0: 65 74 46 6c 61 67 73 28 61 44 61 74 61 2c 20 6e  etFlags(aData, n
a4d0: 44 61 74 61 29 20 26 20 53 45 47 4d 45 4e 54 5f  Data) & SEGMENT_
a4e0: 42 54 52 45 45 5f 46 4c 41 47 29 3d 3d 30 0a 20  BTREE_FLAG)==0. 
a4f0: 20 20 20 20 20 20 26 26 20 70 61 67 65 47 65 74        && pageGet
a500: 4e 52 65 63 28 61 44 61 74 61 2c 20 6e 44 61 74  NRec(aData, nDat
a510: 61 29 3e 30 0a 20 20 20 20 20 20 29 7b 0a 20 20  a)>0.      ){.  
a520: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
a530: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
a540: 66 28 20 70 4e 65 78 74 3d 3d 30 20 29 20 62 72  f( pNext==0 ) br
a550: 65 61 6b 3b 0a 20 20 20 20 73 65 67 6d 65 6e 74  eak;.    segment
a560: 50 74 72 53 65 74 50 61 67 65 28 70 50 74 72 2c  PtrSetPage(pPtr,
a570: 20 70 4e 65 78 74 29 3b 0a 0a 20 20 20 20 2f 2a   pNext);..    /*
a580: 20 54 68 69 73 20 73 68 6f 75 6c 64 20 70 72 6f   This should pro
a590: 62 61 62 6c 79 20 62 65 20 61 6e 20 4c 53 4d 5f  bably be an LSM_
a5a0: 43 4f 52 52 55 50 54 20 65 72 72 6f 72 2e 20 2a  CORRUPT error. *
a5b0: 2f 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63  /.    assert( rc
a5c0: 21 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 28 70 50 74  !=LSM_OK || (pPt
a5d0: 72 2d 3e 66 6c 61 67 73 20 26 20 50 47 46 54 52  r->flags & PGFTR
a5e0: 5f 53 4b 49 50 5f 54 48 49 53 5f 46 4c 41 47 29  _SKIP_THIS_FLAG)
a5f0: 20 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72   );.  }..  retur
a600: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
a610: 69 6e 74 20 70 74 72 46 77 64 50 6f 69 6e 74 65  int ptrFwdPointe
a620: 72 28 0a 20 20 50 61 67 65 20 2a 70 50 61 67 65  r(.  Page *pPage
a630: 2c 0a 20 20 69 6e 74 20 69 43 65 6c 6c 2c 0a 20  ,.  int iCell,. 
a640: 20 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 2c 0a   Segment *pSeg,.
a650: 20 20 4c 73 6d 50 67 6e 6f 20 2a 70 69 50 74 72    LsmPgno *piPtr
a660: 2c 0a 20 20 69 6e 74 20 2a 70 62 46 6f 75 6e 64  ,.  int *pbFound
a670: 0a 29 7b 0a 20 20 50 61 67 65 20 2a 70 50 67 20  .){.  Page *pPg 
a680: 3d 20 70 50 61 67 65 3b 0a 20 20 69 6e 74 20 69  = pPage;.  int i
a690: 46 69 72 73 74 20 3d 20 69 43 65 6c 6c 3b 0a 20  First = iCell;. 
a6a0: 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
a6b0: 3b 0a 0a 20 20 64 6f 20 7b 0a 20 20 20 20 50 61  ;..  do {.    Pa
a6c0: 67 65 20 2a 70 4e 65 78 74 20 3d 20 30 3b 0a 20  ge *pNext = 0;. 
a6d0: 20 20 20 75 38 20 2a 61 44 61 74 61 3b 0a 20 20     u8 *aData;.  
a6e0: 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a 0a 20 20    int nData;..  
a6f0: 20 20 61 44 61 74 61 20 3d 20 6c 73 6d 46 73 50    aData = lsmFsP
a700: 61 67 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44  ageData(pPg, &nD
a710: 61 74 61 29 3b 0a 20 20 20 20 69 66 28 20 28 70  ata);.    if( (p
a720: 61 67 65 47 65 74 46 6c 61 67 73 28 61 44 61 74  ageGetFlags(aDat
a730: 61 2c 20 6e 44 61 74 61 29 20 26 20 53 45 47 4d  a, nData) & SEGM
a740: 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 29 3d  ENT_BTREE_FLAG)=
a750: 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  =0 ){.      int 
a760: 69 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 43 65  i;.      int nCe
a770: 6c 6c 20 3d 20 70 61 67 65 47 65 74 4e 52 65 63  ll = pageGetNRec
a780: 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a  (aData, nData);.
a790: 20 20 20 20 20 20 66 6f 72 28 69 3d 69 46 69 72        for(i=iFir
a7a0: 73 74 3b 20 69 3c 6e 43 65 6c 6c 3b 20 69 2b 2b  st; i<nCell; i++
a7b0: 29 7b 0a 20 20 20 20 20 20 20 20 75 38 20 65 54  ){.        u8 eT
a7c0: 79 70 65 20 3d 20 2a 70 61 67 65 47 65 74 43 65  ype = *pageGetCe
a7d0: 6c 6c 28 61 44 61 74 61 2c 20 6e 44 61 74 61 2c  ll(aData, nData,
a7e0: 20 69 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28   i);.        if(
a7f0: 20 28 65 54 79 70 65 20 26 20 4c 53 4d 5f 53 54   (eType & LSM_ST
a800: 41 52 54 5f 44 45 4c 45 54 45 29 3d 3d 30 20 29  ART_DELETE)==0 )
a810: 7b 0a 20 20 20 20 20 20 20 20 20 20 2a 70 62 46  {.          *pbF
a820: 6f 75 6e 64 20 3d 20 31 3b 0a 20 20 20 20 20 20  ound = 1;.      
a830: 20 20 20 20 2a 70 69 50 74 72 20 3d 20 70 61 67      *piPtr = pag
a840: 65 47 65 74 52 65 63 6f 72 64 50 74 72 28 61 44  eGetRecordPtr(aD
a850: 61 74 61 2c 20 6e 44 61 74 61 2c 20 69 29 20 2b  ata, nData, i) +
a860: 20 70 61 67 65 47 65 74 50 74 72 28 61 44 61 74   pageGetPtr(aDat
a870: 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 20  a, nData);.     
a880: 20 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65       lsmFsPageRe
a890: 6c 65 61 73 65 28 70 50 67 29 3b 0a 20 20 20 20  lease(pPg);.    
a8a0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 4c 53 4d        return LSM
a8b0: 5f 4f 4b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  _OK;.        }. 
a8c0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
a8d0: 20 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50 61    rc = lsmFsDbPa
a8e0: 67 65 4e 65 78 74 28 70 53 65 67 2c 20 70 50 67  geNext(pSeg, pPg
a8f0: 2c 20 31 2c 20 26 70 4e 65 78 74 29 3b 0a 20 20  , 1, &pNext);.  
a900: 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61    lsmFsPageRelea
a910: 73 65 28 70 50 67 29 3b 0a 20 20 20 20 70 50 67  se(pPg);.    pPg
a920: 20 3d 20 70 4e 65 78 74 3b 0a 20 20 20 20 69 46   = pNext;.    iF
a930: 69 72 73 74 20 3d 20 30 3b 0a 20 20 7d 77 68 69  irst = 0;.  }whi
a940: 6c 65 28 20 70 50 67 20 26 26 20 72 63 3d 3d 4c  le( pPg && rc==L
a950: 53 4d 5f 4f 4b 20 29 3b 0a 20 20 6c 73 6d 46 73  SM_OK );.  lsmFs
a960: 50 61 67 65 52 65 6c 65 61 73 65 28 70 50 67 29  PageRelease(pPg)
a970: 3b 0a 0a 20 20 2a 70 62 46 6f 75 6e 64 20 3d 20  ;..  *pbFound = 
a980: 30 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  0;.  return rc;.
a990: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73 6f  }..static int so
a9a0: 72 74 65 64 52 68 73 46 69 72 73 74 28 4d 75 6c  rtedRhsFirst(Mul
a9b0: 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  tiCursor *pCsr, 
a9c0: 4c 65 76 65 6c 20 2a 70 4c 76 6c 2c 20 53 65 67  Level *pLvl, Seg
a9d0: 6d 65 6e 74 50 74 72 20 2a 70 50 74 72 29 7b 0a  mentPtr *pPtr){.
a9e0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 72 63 20 3d    int rc;.  rc =
a9f0: 20 73 65 67 6d 65 6e 74 50 74 72 45 6e 64 28 70   segmentPtrEnd(p
aa00: 43 73 72 2c 20 70 50 74 72 2c 20 30 29 3b 0a 20  Csr, pPtr, 0);. 
aa10: 20 77 68 69 6c 65 28 20 70 50 74 72 2d 3e 70 50   while( pPtr->pP
aa20: 67 20 26 26 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20  g && rc==LSM_OK 
aa30: 29 7b 0a 20 20 20 20 69 6e 74 20 72 65 73 20 3d  ){.    int res =
aa40: 20 73 6f 72 74 65 64 4b 65 79 43 6f 6d 70 61 72   sortedKeyCompar
aa50: 65 28 70 43 73 72 2d 3e 70 44 62 2d 3e 78 43 6d  e(pCsr->pDb->xCm
aa60: 70 2c 0a 20 20 20 20 20 20 20 20 70 4c 76 6c 2d  p,.        pLvl-
aa70: 3e 69 53 70 6c 69 74 54 6f 70 69 63 2c 20 70 4c  >iSplitTopic, pL
aa80: 76 6c 2d 3e 70 53 70 6c 69 74 4b 65 79 2c 20 70  vl->pSplitKey, p
aa90: 4c 76 6c 2d 3e 6e 53 70 6c 69 74 4b 65 79 2c 0a  Lvl->nSplitKey,.
aaa0: 20 20 20 20 20 20 20 20 72 74 54 6f 70 69 63 28          rtTopic(
aab0: 70 50 74 72 2d 3e 65 54 79 70 65 29 2c 20 70 50  pPtr->eType), pP
aac0: 74 72 2d 3e 70 4b 65 79 2c 20 70 50 74 72 2d 3e  tr->pKey, pPtr->
aad0: 6e 4b 65 79 0a 20 20 20 20 29 3b 0a 20 20 20 20  nKey.    );.    
aae0: 69 66 28 20 72 65 73 3c 3d 30 20 29 20 62 72 65  if( res<=0 ) bre
aaf0: 61 6b 3b 0a 20 20 20 20 72 63 20 3d 20 73 65 67  ak;.    rc = seg
ab00: 6d 65 6e 74 50 74 72 41 64 76 61 6e 63 65 28 70  mentPtrAdvance(p
ab10: 43 73 72 2c 20 70 50 74 72 2c 20 30 29 3b 0a 20  Csr, pPtr, 0);. 
ab20: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
ab30: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  }.../*.** This f
ab40: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
ab50: 64 20 61 73 20 70 61 72 74 20 6f 66 20 61 20 53  d as part of a S
ab60: 45 45 4b 5f 47 45 20 6f 70 20 6f 6e 20 61 20 6d  EEK_GE op on a m
ab70: 75 6c 74 69 2d 63 75 72 73 6f 72 20 69 66 20 74  ulti-cursor if t
ab80: 68 65 20 0a 2a 2a 20 46 43 20 70 6f 69 6e 74 65  he .** FC pointe
ab90: 72 20 72 65 61 64 20 66 72 6f 6d 20 73 65 67 6d  r read from segm
aba0: 65 6e 74 20 2a 70 50 74 72 20 63 6f 6d 65 73 20  ent *pPtr comes 
abb0: 66 72 6f 6d 20 61 6e 20 65 6e 74 72 79 20 77 69  from an entry wi
abc0: 74 68 20 74 68 65 20 0a 2a 2a 20 4c 53 4d 5f 53  th the .** LSM_S
abd0: 54 41 52 54 5f 44 45 4c 45 54 45 20 66 6c 61 67  TART_DELETE flag
abe0: 20 73 65 74 2e 20 49 6e 20 74 68 69 73 20 63 61   set. In this ca
abf0: 73 65 20 74 68 65 20 70 6f 69 6e 74 65 72 20 76  se the pointer v
ac00: 61 6c 75 65 20 63 61 6e 6e 6f 74 20 62 65 20 0a  alue cannot be .
ac10: 2a 2a 20 74 72 75 73 74 65 64 2e 20 49 6e 73 74  ** trusted. Inst
ac20: 65 61 64 2c 20 74 68 65 20 70 6f 69 6e 74 65 72  ead, the pointer
ac30: 20 74 68 61 74 20 73 68 6f 75 6c 64 20 62 65 20   that should be 
ac40: 66 6f 6c 6c 6f 77 65 64 20 69 73 20 74 68 61 74  followed is that
ac50: 20 61 73 73 6f 63 69 61 74 65 64 0a 2a 2a 20 77   associated.** w
ac60: 69 74 68 20 74 68 65 20 6e 65 78 74 20 65 6e 74  ith the next ent
ac70: 72 79 20 69 6e 20 2a 70 50 74 72 20 74 68 61 74  ry in *pPtr that
ac80: 20 64 6f 65 73 20 6e 6f 74 20 68 61 76 65 20 4c   does not have L
ac90: 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45 54 45 20  SM_START_DELETE 
aca0: 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 57 68 79 20 74  set..**.** Why t
acb0: 68 65 20 70 6f 69 6e 74 65 72 73 20 63 61 6e 27  he pointers can'
acc0: 74 20 62 65 20 74 72 75 73 74 65 64 3a 0a 2a 2a  t be trusted:.**
acd0: 0a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 4f 44 4f 3a 20  .**.**.** TODO: 
ace0: 54 68 69 73 20 69 73 20 61 20 73 74 6f 70 2d 67  This is a stop-g
acf0: 61 70 20 73 6f 6c 75 74 69 6f 6e 3a 0a 2a 2a 20  ap solution:.** 
ad00: 0a 2a 2a 20 20 20 41 74 20 74 68 65 20 6d 6f 6d  .**   At the mom
ad10: 65 6e 74 2c 20 74 68 69 73 20 66 75 6e 63 74 69  ent, this functi
ad20: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 66 72 6f  on is called fro
ad30: 6d 20 77 69 74 68 69 6e 20 73 65 67 6d 65 6e 74  m within segment
ad40: 50 74 72 53 65 65 6b 28 29 2c 20 0a 2a 2a 20 20  PtrSeek(), .**  
ad50: 20 61 73 20 70 61 72 74 20 6f 66 20 74 68 65 20   as part of the 
ad60: 69 6e 69 74 69 61 6c 20 6c 73 6d 4d 43 75 72 73  initial lsmMCurs
ad70: 6f 72 53 65 65 6b 28 29 20 63 61 6c 6c 2e 20 48  orSeek() call. H
ad80: 6f 77 65 76 65 72 2c 20 63 6f 6e 73 69 64 65 72  owever, consider
ad90: 20 61 20 0a 2a 2a 20 20 20 64 61 74 61 62 61 73   a .**   databas
ada0: 65 20 77 68 65 72 65 20 74 68 65 20 66 6f 6c 6c  e where the foll
adb0: 6f 77 69 6e 67 20 68 61 73 20 6f 63 63 75 72 72  owing has occurr
adc0: 65 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 31  ed:.**.**      1
add0: 2e 20 41 20 72 61 6e 67 65 20 64 65 6c 65 74 65  . A range delete
ade0: 20 72 65 6d 6f 76 65 73 20 6b 65 79 73 20 31 2e   removes keys 1.
adf0: 2e 39 39 39 39 20 75 73 69 6e 67 20 61 20 72 61  .9999 using a ra
ae00: 6e 67 65 20 64 65 6c 65 74 65 2e 0a 2a 2a 20 20  nge delete..**  
ae10: 20 20 20 20 32 2e 20 4b 65 79 73 20 31 20 74 68      2. Keys 1 th
ae20: 72 6f 75 67 68 20 39 39 39 39 20 61 72 65 20 72  rough 9999 are r
ae30: 65 69 6e 73 65 72 74 65 64 2e 0a 2a 2a 20 20 20  einserted..**   
ae40: 20 20 20 33 2e 20 54 68 65 20 6c 65 76 65 6c 73     3. The levels
ae50: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20   containing the 
ae60: 6f 70 73 20 69 6e 20 31 2e 20 61 6e 64 20 32 2e  ops in 1. and 2.
ae70: 20 61 62 6f 76 65 20 61 72 65 20 6d 65 72 67 65   above are merge
ae80: 64 2e 20 43 61 6c 6c 0a 2a 2a 20 20 20 20 20 20  d. Call.**      
ae90: 20 20 20 74 68 69 73 20 6c 65 76 65 6c 20 4e 2e     this level N.
aea0: 20 4c 65 76 65 6c 20 4e 20 63 6f 6e 74 61 69 6e   Level N contain
aeb0: 73 20 46 43 20 70 6f 69 6e 74 65 72 73 20 74 6f  s FC pointers to
aec0: 20 6c 65 76 65 6c 20 4e 2b 31 2e 0a 2a 2a 0a 2a   level N+1..**.*
aed0: 2a 20 20 20 54 68 65 6e 2c 20 69 66 20 74 68 65  *   Then, if the
aee0: 20 75 73 65 72 20 61 74 74 65 6d 70 74 73 20 74   user attempts t
aef0: 6f 20 71 75 65 72 79 20 66 6f 72 20 28 6b 65 79  o query for (key
af00: 3e 3d 32 20 4c 49 4d 49 54 20 31 30 29 2c 20 74  >=2 LIMIT 10), t
af10: 68 65 20 0a 2a 2a 20 20 20 6c 73 6d 4d 43 75 72  he .**   lsmMCur
af20: 73 6f 72 53 65 65 6b 28 29 20 63 61 6c 6c 20 77  sorSeek() call w
af30: 69 6c 6c 20 69 74 65 72 61 74 65 20 74 68 72 6f  ill iterate thro
af40: 75 67 68 20 39 39 39 38 20 65 6e 74 72 69 65 73  ugh 9998 entries
af50: 20 73 65 61 72 63 68 69 6e 67 20 66 6f 72 20 61   searching for a
af60: 20 0a 2a 2a 20 20 20 70 6f 69 6e 74 65 72 20 64   .**   pointer d
af70: 6f 77 6e 20 74 6f 20 74 68 65 20 6c 65 76 65 6c  own to the level
af80: 20 4e 2b 31 20 74 68 61 74 20 69 73 20 6e 65 76   N+1 that is nev
af90: 65 72 20 61 63 74 75 61 6c 6c 79 20 75 73 65 64  er actually used
afa0: 2e 20 49 74 20 77 6f 75 6c 64 20 62 65 0a 2a 2a  . It would be.**
afb0: 20 20 20 6d 75 63 68 20 62 65 74 74 65 72 20 69     much better i
afc0: 66 20 74 68 65 20 6d 75 6c 74 69 2d 63 75 72 73  f the multi-curs
afd0: 6f 72 20 63 6f 75 6c 64 20 64 6f 20 74 68 69 73  or could do this
afe0: 20 6c 61 7a 69 6c 79 20 2d 20 6f 6e 6c 79 20 73   lazily - only s
aff0: 65 65 6b 20 74 6f 20 74 68 65 0a 2a 2a 20 20 20  eek to the.**   
b000: 6c 65 76 65 6c 20 28 4e 2b 31 29 20 70 61 67 65  level (N+1) page
b010: 20 61 66 74 65 72 20 74 68 65 20 75 73 65 72 20   after the user 
b020: 68 61 73 20 6d 6f 76 65 64 20 74 68 65 20 63 75  has moved the cu
b030: 72 73 6f 72 20 6f 6e 20 6c 65 76 65 6c 20 4e 20  rsor on level N 
b040: 70 61 73 73 65 64 0a 2a 2a 20 20 20 74 68 65 20  passed.**   the 
b050: 62 69 67 20 72 61 6e 67 65 2d 64 65 6c 65 74 65  big range-delete
b060: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
b070: 73 65 67 6d 65 6e 74 50 74 72 46 77 64 50 6f 69  segmentPtrFwdPoi
b080: 6e 74 65 72 28 0a 20 20 4d 75 6c 74 69 43 75 72  nter(.  MultiCur
b090: 73 6f 72 20 2a 70 43 73 72 2c 20 20 20 20 20 20  sor *pCsr,      
b0a0: 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 6c 74 69          /* Multi
b0b0: 2d 63 75 72 73 6f 72 20 70 50 74 72 20 62 65 6c  -cursor pPtr bel
b0c0: 6f 6e 67 73 20 74 6f 20 2a 2f 0a 20 20 53 65 67  ongs to */.  Seg
b0d0: 6d 65 6e 74 50 74 72 20 2a 70 50 74 72 2c 20 20  mentPtr *pPtr,  
b0e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
b0f0: 53 65 67 6d 65 6e 74 2d 70 6f 69 6e 74 65 72 20  Segment-pointer 
b100: 74 6f 20 65 78 74 72 61 63 74 20 46 43 20 70 74  to extract FC pt
b110: 72 20 66 72 6f 6d 20 2a 2f 0a 20 20 4c 73 6d 50  r from */.  LsmP
b120: 67 6e 6f 20 2a 70 69 50 74 72 20 20 20 20 20 20  gno *piPtr      
b130: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
b140: 55 54 3a 20 46 43 20 70 6f 69 6e 74 65 72 20 76  UT: FC pointer v
b150: 61 6c 75 65 20 2a 2f 0a 29 7b 0a 20 20 4c 65 76  alue */.){.  Lev
b160: 65 6c 20 2a 70 4c 76 6c 20 3d 20 70 50 74 72 2d  el *pLvl = pPtr-
b170: 3e 70 4c 65 76 65 6c 3b 0a 20 20 4c 65 76 65 6c  >pLevel;.  Level
b180: 20 2a 70 4e 65 78 74 20 3d 20 70 4c 76 6c 2d 3e   *pNext = pLvl->
b190: 70 4e 65 78 74 3b 0a 20 20 50 61 67 65 20 2a 70  pNext;.  Page *p
b1a0: 50 67 20 3d 20 70 50 74 72 2d 3e 70 50 67 3b 0a  Pg = pPtr->pPg;.
b1b0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20    int rc;.  int 
b1c0: 62 46 6f 75 6e 64 3b 0a 20 20 4c 73 6d 50 67 6e  bFound;.  LsmPgn
b1d0: 6f 20 69 4f 75 74 20 3d 20 30 3b 0a 0a 20 20 69  o iOut = 0;..  i
b1e0: 66 28 20 70 50 74 72 2d 3e 70 53 65 67 3d 3d 26  f( pPtr->pSeg==&
b1f0: 70 4c 76 6c 2d 3e 6c 68 73 20 7c 7c 20 70 50 74  pLvl->lhs || pPt
b200: 72 2d 3e 70 53 65 67 3d 3d 26 70 4c 76 6c 2d 3e  r->pSeg==&pLvl->
b210: 61 52 68 73 5b 70 4c 76 6c 2d 3e 6e 52 69 67 68  aRhs[pLvl->nRigh
b220: 74 2d 31 5d 20 29 7b 0a 20 20 20 20 69 66 28 20  t-1] ){.    if( 
b230: 70 4e 65 78 74 3d 3d 30 20 0a 20 20 20 20 20 20  pNext==0 .      
b240: 20 20 7c 7c 20 28 70 4e 65 78 74 2d 3e 6e 52 69    || (pNext->nRi
b250: 67 68 74 3d 3d 30 20 26 26 20 70 4e 65 78 74 2d  ght==0 && pNext-
b260: 3e 6c 68 73 2e 69 52 6f 6f 74 29 0a 20 20 20 20  >lhs.iRoot).    
b270: 20 20 20 20 7c 7c 20 28 70 4e 65 78 74 2d 3e 6e      || (pNext->n
b280: 52 69 67 68 74 21 3d 30 20 26 26 20 70 4e 65 78  Right!=0 && pNex
b290: 74 2d 3e 61 52 68 73 5b 30 5d 2e 69 52 6f 6f 74  t->aRhs[0].iRoot
b2a0: 29 0a 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20  ).      ){.     
b2b0: 20 2f 2a 20 44 6f 20 6e 6f 74 68 69 6e 67 2e 20   /* Do nothing. 
b2c0: 54 68 65 20 70 6f 69 6e 74 65 72 20 77 69 6c 6c  The pointer will
b2d0: 20 6e 6f 74 20 62 65 20 75 73 65 64 20 61 6e 79   not be used any
b2e0: 77 61 79 2e 20 2a 2f 0a 20 20 20 20 20 20 72 65  way. */.      re
b2f0: 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 20  turn LSM_OK;.   
b300: 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20   }.  }else{.    
b310: 69 66 28 20 70 50 74 72 5b 31 5d 2e 70 53 65 67  if( pPtr[1].pSeg
b320: 2d 3e 69 52 6f 6f 74 20 29 7b 0a 20 20 20 20 20  ->iRoot ){.     
b330: 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a   return LSM_OK;.
b340: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20      }.  }..  /* 
b350: 53 65 61 72 63 68 20 66 6f 72 20 61 20 70 6f 69  Search for a poi
b360: 6e 74 65 72 20 77 69 74 68 69 6e 20 74 68 65 20  nter within the 
b370: 63 75 72 72 65 6e 74 20 73 65 67 6d 65 6e 74 2e  current segment.
b380: 20 2a 2f 0a 20 20 6c 73 6d 46 73 50 61 67 65 52   */.  lsmFsPageR
b390: 65 66 28 70 50 67 29 3b 0a 20 20 72 63 20 3d 20  ef(pPg);.  rc = 
b3a0: 70 74 72 46 77 64 50 6f 69 6e 74 65 72 28 70 50  ptrFwdPointer(pP
b3b0: 67 2c 20 70 50 74 72 2d 3e 69 43 65 6c 6c 2c 20  g, pPtr->iCell, 
b3c0: 70 50 74 72 2d 3e 70 53 65 67 2c 20 26 69 4f 75  pPtr->pSeg, &iOu
b3d0: 74 2c 20 26 62 46 6f 75 6e 64 29 3b 0a 0a 20 20  t, &bFound);..  
b3e0: 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26  if( rc==LSM_OK &
b3f0: 26 20 62 46 6f 75 6e 64 3d 3d 30 20 29 7b 0a 20  & bFound==0 ){. 
b400: 20 20 20 2f 2a 20 54 68 69 73 20 63 61 73 65 20     /* This case 
b410: 68 61 70 70 65 6e 73 20 77 68 65 6e 20 70 50 74  happens when pPt
b420: 72 20 70 6f 69 6e 74 73 20 74 6f 20 74 68 65 20  r points to the 
b430: 6c 65 66 74 2d 68 61 6e 64 2d 73 69 64 65 20 6f  left-hand-side o
b440: 66 20 61 20 73 65 67 6d 65 6e 74 0a 20 20 20 20  f a segment.    
b450: 2a 2a 20 63 75 72 72 65 6e 74 6c 79 20 75 6e 64  ** currently und
b460: 65 72 67 6f 69 6e 67 20 61 6e 20 69 6e 63 72 65  ergoing an incre
b470: 6d 65 6e 74 61 6c 20 6d 65 72 67 65 2e 20 49 6e  mental merge. In
b480: 20 74 68 69 73 20 63 61 73 65 2c 20 6a 75 6d 70   this case, jump
b490: 20 74 6f 20 74 68 65 0a 20 20 20 20 2a 2a 20 6f   to the.    ** o
b4a0: 6c 64 65 73 74 20 73 65 67 6d 65 6e 74 20 69 6e  ldest segment in
b4b0: 20 74 68 65 20 72 69 67 68 74 2d 68 61 6e 64 2d   the right-hand-
b4c0: 73 69 64 65 20 6f 66 20 74 68 65 20 73 61 6d 65  side of the same
b4d0: 20 6c 65 76 65 6c 20 61 6e 64 20 63 6f 6e 74 69   level and conti
b4e0: 6e 75 65 0a 20 20 20 20 2a 2a 20 73 65 61 72 63  nue.    ** searc
b4f0: 68 69 6e 67 2e 20 42 75 74 20 2d 20 64 6f 20 6e  hing. But - do n
b500: 6f 74 20 63 6f 6e 73 69 64 65 72 20 61 6e 79 20  ot consider any 
b510: 6b 65 79 73 20 73 6d 61 6c 6c 65 72 20 74 68 61  keys smaller tha
b520: 6e 20 74 68 65 20 6c 65 76 65 6c 73 0a 20 20 20  n the levels.   
b530: 20 2a 2a 20 73 70 6c 69 74 2d 6b 65 79 2e 20 2a   ** split-key. *
b540: 2f 0a 20 20 20 20 53 65 67 6d 65 6e 74 50 74 72  /.    SegmentPtr
b550: 20 70 74 72 3b 0a 0a 20 20 20 20 69 66 28 20 70   ptr;..    if( p
b560: 50 74 72 2d 3e 70 4c 65 76 65 6c 2d 3e 6e 52 69  Ptr->pLevel->nRi
b570: 67 68 74 3d 3d 30 20 7c 7c 20 70 50 74 72 2d 3e  ght==0 || pPtr->
b580: 70 53 65 67 21 3d 26 70 50 74 72 2d 3e 70 4c 65  pSeg!=&pPtr->pLe
b590: 76 65 6c 2d 3e 6c 68 73 20 29 7b 0a 20 20 20 20  vel->lhs ){.    
b5a0: 20 20 72 65 74 75 72 6e 20 4c 53 4d 5f 43 4f 52    return LSM_COR
b5b0: 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20 20 7d  RUPT_BKPT;.    }
b5c0: 0a 0a 20 20 20 20 6d 65 6d 73 65 74 28 26 70 74  ..    memset(&pt
b5d0: 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53 65 67  r, 0, sizeof(Seg
b5e0: 6d 65 6e 74 50 74 72 29 29 3b 0a 20 20 20 20 70  mentPtr));.    p
b5f0: 74 72 2e 70 4c 65 76 65 6c 20 3d 20 70 50 74 72  tr.pLevel = pPtr
b600: 2d 3e 70 4c 65 76 65 6c 3b 0a 20 20 20 20 70 74  ->pLevel;.    pt
b610: 72 2e 70 53 65 67 20 3d 20 26 70 74 72 2e 70 4c  r.pSeg = &ptr.pL
b620: 65 76 65 6c 2d 3e 61 52 68 73 5b 70 74 72 2e 70  evel->aRhs[ptr.p
b630: 4c 65 76 65 6c 2d 3e 6e 52 69 67 68 74 2d 31 5d  Level->nRight-1]
b640: 3b 0a 20 20 20 20 72 63 20 3d 20 73 6f 72 74 65  ;.    rc = sorte
b650: 64 52 68 73 46 69 72 73 74 28 70 43 73 72 2c 20  dRhsFirst(pCsr, 
b660: 70 74 72 2e 70 4c 65 76 65 6c 2c 20 26 70 74 72  ptr.pLevel, &ptr
b670: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  );.    if( rc==L
b680: 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  SM_OK ){.      r
b690: 63 20 3d 20 70 74 72 46 77 64 50 6f 69 6e 74 65  c = ptrFwdPointe
b6a0: 72 28 70 74 72 2e 70 50 67 2c 20 70 74 72 2e 69  r(ptr.pPg, ptr.i
b6b0: 43 65 6c 6c 2c 20 70 74 72 2e 70 53 65 67 2c 20  Cell, ptr.pSeg, 
b6c0: 26 69 4f 75 74 2c 20 26 62 46 6f 75 6e 64 29 3b  &iOut, &bFound);
b6d0: 0a 20 20 20 20 20 20 70 74 72 2e 70 50 67 20 3d  .      ptr.pPg =
b6e0: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 65   0;.    }.    se
b6f0: 67 6d 65 6e 74 50 74 72 52 65 73 65 74 28 26 70  gmentPtrReset(&p
b700: 74 72 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 2a  tr, 0);.  }..  *
b710: 70 69 50 74 72 20 3d 20 69 4f 75 74 3b 0a 20 20  piPtr = iOut;.  
b720: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
b730: 61 74 69 63 20 69 6e 74 20 73 65 67 6d 65 6e 74  atic int segment
b740: 50 74 72 53 65 65 6b 28 0a 20 20 4d 75 6c 74 69  PtrSeek(.  Multi
b750: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 20 20  Cursor *pCsr,   
b760: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
b770: 72 73 6f 72 20 63 6f 6e 74 65 78 74 20 2a 2f 0a  rsor context */.
b780: 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50    SegmentPtr *pP
b790: 74 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  tr,             
b7a0: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
b7b0: 73 65 65 6b 20 2a 2f 0a 20 20 69 6e 74 20 69 54  seek */.  int iT
b7c0: 6f 70 69 63 2c 20 20 20 20 20 20 20 20 20 20 20  opic,           
b7d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4b 65 79            /* Key
b7e0: 20 74 6f 70 69 63 20 74 6f 20 73 65 65 6b 20 74   topic to seek t
b7f0: 6f 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 4b 65  o */.  void *pKe
b800: 79 2c 20 69 6e 74 20 6e 4b 65 79 2c 20 20 20 20  y, int nKey,    
b810: 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 20 74 6f         /* Key to
b820: 20 73 65 65 6b 20 74 6f 20 2a 2f 0a 20 20 69 6e   seek to */.  in
b830: 74 20 65 53 65 65 6b 2c 20 20 20 20 20 20 20 20  t eSeek,        
b840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
b850: 20 53 65 61 72 63 68 20 62 69 61 73 20 2d 20 73   Search bias - s
b860: 65 65 20 61 62 6f 76 65 20 2a 2f 0a 20 20 69 6e  ee above */.  in
b870: 74 20 2a 70 69 50 74 72 2c 20 20 20 20 20 20 20  t *piPtr,       
b880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
b890: 20 4f 55 54 3a 20 46 43 20 70 6f 69 6e 74 65 72   OUT: FC pointer
b8a0: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 62 53 74 6f   */.  int *pbSto
b8b0: 70 0a 29 7b 0a 20 20 69 6e 74 20 28 2a 78 43 6d  p.){.  int (*xCm
b8c0: 70 29 28 76 6f 69 64 20 2a 2c 20 69 6e 74 2c 20  p)(void *, int, 
b8d0: 76 6f 69 64 20 2a 2c 20 69 6e 74 29 20 3d 20 70  void *, int) = p
b8e0: 43 73 72 2d 3e 70 44 62 2d 3e 78 43 6d 70 3b 0a  Csr->pDb->xCmp;.
b8f0: 20 20 69 6e 74 20 72 65 73 20 3d 20 30 3b 20 20    int res = 0;  
b900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b910: 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20        /* Result 
b920: 6f 66 20 63 6f 6d 70 61 72 69 73 6f 6e 20 6f 70  of comparison op
b930: 65 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74  eration */.  int
b940: 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20   rc = LSM_OK;.  
b950: 69 6e 74 20 69 4d 69 6e 3b 0a 20 20 69 6e 74 20  int iMin;.  int 
b960: 69 4d 61 78 3b 0a 20 20 4c 73 6d 50 67 6e 6f 20  iMax;.  LsmPgno 
b970: 69 50 74 72 4f 75 74 20 3d 20 30 3b 0a 0a 20 20  iPtrOut = 0;..  
b980: 2f 2a 20 49 66 20 74 68 65 20 63 75 72 72 65 6e  /* If the curren
b990: 74 20 70 61 67 65 20 63 6f 6e 74 61 69 6e 73 20  t page contains 
b9a0: 61 6e 20 6f 76 65 72 73 69 7a 65 64 20 65 6e 74  an oversized ent
b9b0: 72 79 2c 20 74 68 65 6e 20 74 68 65 72 65 20 61  ry, then there a
b9c0: 72 65 20 6e 6f 0a 20 20 2a 2a 20 70 6f 69 6e 74  re no.  ** point
b9d0: 65 72 73 20 74 6f 20 6f 6e 65 20 6f 72 20 6d 6f  ers to one or mo
b9e0: 72 65 20 6f 66 20 74 68 65 20 73 75 62 73 65 71  re of the subseq
b9f0: 75 65 6e 74 20 70 61 67 65 73 20 69 6e 20 74 68  uent pages in th
ba00: 65 20 73 6f 72 74 65 64 20 72 75 6e 2e 0a 20 20  e sorted run..  
ba10: 2a 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ** The following
ba20: 20 63 61 6c 6c 20 65 6e 73 75 72 65 73 20 74 68   call ensures th
ba30: 61 74 20 74 68 65 20 73 65 67 6d 65 6e 74 2d 70  at the segment-p
ba40: 74 72 20 70 6f 69 6e 74 73 20 74 6f 20 74 68 65  tr points to the
ba50: 20 63 6f 72 72 65 63 74 20 0a 20 20 2a 2a 20 70   correct .  ** p
ba60: 61 67 65 20 69 6e 20 74 68 69 73 20 63 61 73 65  age in this case
ba70: 2e 20 20 2a 2f 0a 20 20 72 63 20 3d 20 73 65 67  .  */.  rc = seg
ba80: 6d 65 6e 74 50 74 72 53 65 61 72 63 68 4f 76 65  mentPtrSearchOve
ba90: 72 73 69 7a 65 64 28 70 43 73 72 2c 20 70 50 74  rsized(pCsr, pPt
baa0: 72 2c 20 69 54 6f 70 69 63 2c 20 70 4b 65 79 2c  r, iTopic, pKey,
bab0: 20 6e 4b 65 79 29 3b 0a 20 20 69 50 74 72 4f 75   nKey);.  iPtrOu
bac0: 74 20 3d 20 70 50 74 72 2d 3e 69 50 74 72 3b 0a  t = pPtr->iPtr;.
bad0: 0a 20 20 2f 2a 20 41 73 73 65 72 74 20 74 68 61  .  /* Assert tha
bae0: 74 20 74 68 69 73 20 70 61 67 65 20 69 73 20 74  t this page is t
baf0: 68 65 20 72 69 67 68 74 20 70 61 67 65 20 6f 66  he right page of
bb00: 20 74 68 69 73 20 73 65 67 6d 65 6e 74 20 66 6f   this segment fo
bb10: 72 20 74 68 65 20 6b 65 79 0a 20 20 2a 2a 20 74  r the key.  ** t
bb20: 68 61 74 20 77 65 20 61 72 65 20 73 65 61 72 63  hat we are searc
bb30: 68 69 6e 67 20 66 6f 72 2e 20 44 6f 20 74 68 69  hing for. Do thi
bb40: 73 20 62 79 20 6c 6f 61 64 69 6e 67 20 70 61 67  s by loading pag
bb50: 65 20 28 69 50 67 2d 31 29 20 61 6e 64 20 74 65  e (iPg-1) and te
bb60: 73 74 69 6e 67 0a 20 20 2a 2a 20 74 68 61 74 20  sting.  ** that 
bb70: 70 4b 65 79 2f 6e 4b 65 79 20 69 73 20 67 72 65  pKey/nKey is gre
bb80: 61 74 65 72 20 74 68 61 6e 20 61 6c 6c 20 6b 65  ater than all ke
bb90: 79 73 20 6f 6e 20 74 68 61 74 20 70 61 67 65 2c  ys on that page,
bba0: 20 61 6e 64 20 74 68 65 6e 20 62 79 20 0a 20 20   and then by .  
bbb0: 2a 2a 20 6c 6f 61 64 69 6e 67 20 28 69 50 67 2b  ** loading (iPg+
bbc0: 31 29 20 61 6e 64 20 74 65 73 74 69 6e 67 20 74  1) and testing t
bbd0: 68 61 74 20 70 4b 65 79 2f 6e 4b 65 79 20 69 73  hat pKey/nKey is
bbe0: 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 61 6c   smaller than al
bbf0: 6c 0a 20 20 2a 2a 20 74 68 65 20 6b 65 79 73 20  l.  ** the keys 
bc00: 69 74 20 68 6f 75 73 65 73 2e 20 20 0a 20 20 2a  it houses.  .  *
bc10: 2a 0a 20 20 2a 2a 20 54 4f 44 4f 3a 20 57 69 74  *.  ** TODO: Wit
bc20: 68 20 72 61 6e 67 65 2d 64 65 6c 65 74 65 73 20  h range-deletes 
bc30: 69 6e 20 74 68 65 20 74 72 65 65 2c 20 74 68 65  in the tree, the
bc40: 20 74 65 73 74 20 64 65 73 63 72 69 62 65 64 20   test described 
bc50: 61 62 6f 76 65 20 6d 61 79 20 66 61 69 6c 2e 0a  above may fail..
bc60: 20 20 2a 2f 0a 23 69 66 20 30 0a 20 20 61 73 73    */.#if 0.  ass
bc70: 65 72 74 28 20 61 73 73 65 72 74 4b 65 79 4c 6f  ert( assertKeyLo
bc80: 63 61 74 69 6f 6e 28 70 43 73 72 2c 20 70 50 74  cation(pCsr, pPt
bc90: 72 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 20 29  r, pKey, nKey) )
bca0: 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 61 73 73 65  ;.#endif..  asse
bcb0: 72 74 28 20 70 50 74 72 2d 3e 6e 43 65 6c 6c 3e  rt( pPtr->nCell>
bcc0: 30 20 0a 20 20 20 20 20 20 20 7c 7c 20 70 50 74  0 .       || pPt
bcd0: 72 2d 3e 70 53 65 67 2d 3e 6e 53 69 7a 65 3d 3d  r->pSeg->nSize==
bce0: 31 20 0a 20 20 20 20 20 20 20 7c 7c 20 6c 73 6d  1 .       || lsm
bcf0: 46 73 44 62 50 61 67 65 49 73 4c 61 73 74 28 70  FsDbPageIsLast(p
bd00: 50 74 72 2d 3e 70 53 65 67 2c 20 70 50 74 72 2d  Ptr->pSeg, pPtr-
bd10: 3e 70 50 67 29 0a 20 20 29 3b 0a 20 20 69 66 28  >pPg).  );.  if(
bd20: 20 70 50 74 72 2d 3e 6e 43 65 6c 6c 3d 3d 30 20   pPtr->nCell==0 
bd30: 29 7b 0a 20 20 20 20 73 65 67 6d 65 6e 74 50 74  ){.    segmentPt
bd40: 72 52 65 73 65 74 28 70 50 74 72 2c 20 4c 53 4d  rReset(pPtr, LSM
bd50: 5f 53 45 47 4d 45 4e 54 50 54 52 5f 46 52 45 45  _SEGMENTPTR_FREE
bd60: 5f 54 48 52 45 53 48 4f 4c 44 29 3b 0a 20 20 7d  _THRESHOLD);.  }
bd70: 65 6c 73 65 7b 0a 20 20 20 20 69 4d 69 6e 20 3d  else{.    iMin =
bd80: 20 30 3b 0a 20 20 20 20 69 4d 61 78 20 3d 20 70   0;.    iMax = p
bd90: 50 74 72 2d 3e 6e 43 65 6c 6c 2d 31 3b 0a 0a 20  Ptr->nCell-1;.. 
bda0: 20 20 20 77 68 69 6c 65 28 20 31 20 29 7b 0a 20     while( 1 ){. 
bdb0: 20 20 20 20 20 69 6e 74 20 69 54 72 79 20 3d 20       int iTry = 
bdc0: 28 69 4d 69 6e 2b 69 4d 61 78 29 2f 32 3b 0a 20  (iMin+iMax)/2;. 
bdd0: 20 20 20 20 20 76 6f 69 64 20 2a 70 4b 65 79 54       void *pKeyT
bde0: 3b 20 69 6e 74 20 6e 4b 65 79 54 3b 20 20 20 20  ; int nKeyT;    
bdf0: 20 20 20 2f 2a 20 4b 65 79 20 66 6f 72 20 63 65     /* Key for ce
be00: 6c 6c 20 69 54 72 79 20 2a 2f 0a 20 20 20 20 20  ll iTry */.     
be10: 20 69 6e 74 20 69 54 6f 70 69 63 54 3b 0a 0a 20   int iTopicT;.. 
be20: 20 20 20 20 20 61 73 73 65 72 74 28 20 69 54 72       assert( iTr
be30: 79 3c 69 4d 61 78 20 7c 7c 20 69 4d 69 6e 3d 3d  y<iMax || iMin==
be40: 69 4d 61 78 20 29 3b 0a 0a 20 20 20 20 20 20 72  iMax );..      r
be50: 63 20 3d 20 73 65 67 6d 65 6e 74 50 74 72 4c 6f  c = segmentPtrLo
be60: 61 64 43 65 6c 6c 28 70 50 74 72 2c 20 69 54 72  adCell(pPtr, iTr
be70: 79 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  y);.      if( rc
be80: 21 3d 4c 53 4d 5f 4f 4b 20 29 20 62 72 65 61 6b  !=LSM_OK ) break
be90: 3b 0a 0a 20 20 20 20 20 20 73 65 67 6d 65 6e 74  ;..      segment
bea0: 50 74 72 4b 65 79 28 70 50 74 72 2c 20 26 70 4b  PtrKey(pPtr, &pK
beb0: 65 79 54 2c 20 26 6e 4b 65 79 54 29 3b 0a 20 20  eyT, &nKeyT);.  
bec0: 20 20 20 20 69 54 6f 70 69 63 54 20 3d 20 72 74      iTopicT = rt
bed0: 54 6f 70 69 63 28 70 50 74 72 2d 3e 65 54 79 70  Topic(pPtr->eTyp
bee0: 65 29 3b 0a 0a 20 20 20 20 20 20 72 65 73 20 3d  e);..      res =
bef0: 20 73 6f 72 74 65 64 4b 65 79 43 6f 6d 70 61 72   sortedKeyCompar
bf00: 65 28 78 43 6d 70 2c 20 69 54 6f 70 69 63 54 2c  e(xCmp, iTopicT,
bf10: 20 70 4b 65 79 54 2c 20 6e 4b 65 79 54 2c 20 69   pKeyT, nKeyT, i
bf20: 54 6f 70 69 63 2c 20 70 4b 65 79 2c 20 6e 4b 65  Topic, pKey, nKe
bf30: 79 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 65  y);.      if( re
bf40: 73 3c 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  s<=0 ){.        
bf50: 69 50 74 72 4f 75 74 20 3d 20 70 50 74 72 2d 3e  iPtrOut = pPtr->
bf60: 69 50 74 72 20 2b 20 70 50 74 72 2d 3e 69 50 67  iPtr + pPtr->iPg
bf70: 50 74 72 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20  Ptr;.      }..  
bf80: 20 20 20 20 69 66 28 20 72 65 73 3d 3d 30 20 7c      if( res==0 |
bf90: 7c 20 69 4d 69 6e 3d 3d 69 4d 61 78 20 29 7b 0a  | iMin==iMax ){.
bfa0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
bfb0: 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72       }else if( r
bfc0: 65 73 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20  es>0 ){.        
bfd0: 69 4d 61 78 20 3d 20 4c 53 4d 5f 4d 41 58 28 69  iMax = LSM_MAX(i
bfe0: 54 72 79 2d 31 2c 20 69 4d 69 6e 29 3b 0a 20 20  Try-1, iMin);.  
bff0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
c000: 20 20 20 69 4d 69 6e 20 3d 20 69 54 72 79 2b 31     iMin = iTry+1
c010: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
c020: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d  .    if( rc==LSM
c030: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 61 73 73  _OK ){.      ass
c040: 65 72 74 28 20 72 65 73 3d 3d 30 20 7c 7c 20 28  ert( res==0 || (
c050: 69 4d 69 6e 3d 3d 69 4d 61 78 20 26 26 20 69 4d  iMin==iMax && iM
c060: 69 6e 3e 3d 30 20 26 26 20 69 4d 69 6e 3c 70 50  in>=0 && iMin<pP
c070: 74 72 2d 3e 6e 43 65 6c 6c 29 20 29 3b 0a 20 20  tr->nCell) );.  
c080: 20 20 20 20 69 66 28 20 72 65 73 20 29 7b 0a 20      if( res ){. 
c090: 20 20 20 20 20 20 20 72 63 20 3d 20 73 65 67 6d         rc = segm
c0a0: 65 6e 74 50 74 72 4c 6f 61 64 43 65 6c 6c 28 70  entPtrLoadCell(p
c0b0: 50 74 72 2c 20 69 4d 69 6e 29 3b 0a 20 20 20 20  Ptr, iMin);.    
c0c0: 20 20 7d 0a 20 20 20 20 20 20 61 73 73 65 72 74    }.      assert
c0d0: 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20  ( rc!=LSM_OK || 
c0e0: 72 65 73 3e 30 20 7c 7c 20 69 50 74 72 4f 75 74  res>0 || iPtrOut
c0f0: 3d 3d 28 70 50 74 72 2d 3e 69 50 74 72 20 2b 20  ==(pPtr->iPtr + 
c100: 70 50 74 72 2d 3e 69 50 67 50 74 72 29 20 29 3b  pPtr->iPgPtr) );
c110: 0a 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ..      if( rc==
c120: 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  LSM_OK ){.      
c130: 20 20 73 77 69 74 63 68 28 20 65 53 65 65 6b 20    switch( eSeek 
c140: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 63 61 73  ){.          cas
c150: 65 20 4c 53 4d 5f 53 45 45 4b 5f 45 51 3a 20 7b  e LSM_SEEK_EQ: {
c160: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74  .            int
c170: 20 65 54 79 70 65 20 3d 20 70 50 74 72 2d 3e 65   eType = pPtr->e
c180: 54 79 70 65 3b 0a 20 20 20 20 20 20 20 20 20 20  Type;.          
c190: 20 20 69 66 28 20 28 72 65 73 3c 30 20 26 26 20    if( (res<0 && 
c1a0: 28 65 54 79 70 65 20 26 20 4c 53 4d 5f 53 54 41  (eType & LSM_STA
c1b0: 52 54 5f 44 45 4c 45 54 45 29 29 0a 20 20 20 20  RT_DELETE)).    
c1c0: 20 20 20 20 20 20 20 20 20 7c 7c 20 28 72 65 73           || (res
c1d0: 3e 30 20 26 26 20 28 65 54 79 70 65 20 26 20 4c  >0 && (eType & L
c1e0: 53 4d 5f 45 4e 44 5f 44 45 4c 45 54 45 29 29 0a  SM_END_DELETE)).
c1f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 7c 7c 20               || 
c200: 28 72 65 73 3d 3d 30 20 26 26 20 28 65 54 79 70  (res==0 && (eTyp
c210: 65 20 26 20 4c 53 4d 5f 50 4f 49 4e 54 5f 44 45  e & LSM_POINT_DE
c220: 4c 45 54 45 29 29 0a 20 20 20 20 20 20 20 20 20  LETE)).         
c230: 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20     ){.          
c240: 20 20 20 20 2a 70 62 53 74 6f 70 20 3d 20 31 3b      *pbStop = 1;
c250: 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 65 6c  .            }el
c260: 73 65 20 69 66 28 20 72 65 73 3d 3d 30 20 26 26  se if( res==0 &&
c270: 20 28 65 54 79 70 65 20 26 20 4c 53 4d 5f 49 4e   (eType & LSM_IN
c280: 53 45 52 54 29 20 29 7b 0a 20 20 20 20 20 20 20  SERT) ){.       
c290: 20 20 20 20 20 20 20 6c 73 6d 5f 65 6e 76 20 2a         lsm_env *
c2a0: 70 45 6e 76 20 3d 20 70 43 73 72 2d 3e 70 44 62  pEnv = pCsr->pDb
c2b0: 2d 3e 70 45 6e 76 3b 0a 20 20 20 20 20 20 20 20  ->pEnv;.        
c2c0: 20 20 20 20 20 20 2a 70 62 53 74 6f 70 20 3d 20        *pbStop = 
c2d0: 31 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  1;.             
c2e0: 20 70 43 73 72 2d 3e 65 54 79 70 65 20 3d 20 70   pCsr->eType = p
c2f0: 50 74 72 2d 3e 65 54 79 70 65 3b 0a 20 20 20 20  Ptr->eType;.    
c300: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73            rc = s
c310: 6f 72 74 65 64 42 6c 6f 62 53 65 74 28 70 45 6e  ortedBlobSet(pEn
c320: 76 2c 20 26 70 43 73 72 2d 3e 6b 65 79 2c 20 70  v, &pCsr->key, p
c330: 50 74 72 2d 3e 70 4b 65 79 2c 20 70 50 74 72 2d  Ptr->pKey, pPtr-
c340: 3e 6e 4b 65 79 29 3b 0a 20 20 20 20 20 20 20 20  >nKey);.        
c350: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53        if( rc==LS
c360: 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  M_OK ){.        
c370: 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 6f 72          rc = sor
c380: 74 65 64 42 6c 6f 62 53 65 74 28 70 45 6e 76 2c  tedBlobSet(pEnv,
c390: 20 26 70 43 73 72 2d 3e 76 61 6c 2c 20 70 50 74   &pCsr->val, pPt
c3a0: 72 2d 3e 70 56 61 6c 2c 20 70 50 74 72 2d 3e 6e  r->pVal, pPtr->n
c3b0: 56 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Val);.          
c3c0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20      }.          
c3d0: 20 20 20 20 70 43 73 72 2d 3e 66 6c 61 67 73 20      pCsr->flags 
c3e0: 7c 3d 20 43 55 52 53 4f 52 5f 53 45 45 4b 5f 45  |= CURSOR_SEEK_E
c3f0: 51 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d  Q;.            }
c400: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65 67  .            seg
c410: 6d 65 6e 74 50 74 72 52 65 73 65 74 28 70 50 74  mentPtrReset(pPt
c420: 72 2c 20 4c 53 4d 5f 53 45 47 4d 45 4e 54 50 54  r, LSM_SEGMENTPT
c430: 52 5f 46 52 45 45 5f 54 48 52 45 53 48 4f 4c 44  R_FREE_THRESHOLD
c440: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 62  );.            b
c450: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20  reak;.          
c460: 7d 0a 20 20 20 20 20 20 20 20 20 20 63 61 73 65  }.          case
c470: 20 4c 53 4d 5f 53 45 45 4b 5f 4c 45 3a 0a 20 20   LSM_SEEK_LE:.  
c480: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 72 65            if( re
c490: 73 3e 30 20 29 20 72 63 20 3d 20 73 65 67 6d 65  s>0 ) rc = segme
c4a0: 6e 74 50 74 72 41 64 76 61 6e 63 65 28 70 43 73  ntPtrAdvance(pCs
c4b0: 72 2c 20 70 50 74 72 2c 20 31 29 3b 0a 20 20 20  r, pPtr, 1);.   
c4c0: 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a           break;.
c4d0: 20 20 20 20 20 20 20 20 20 20 63 61 73 65 20 4c            case L
c4e0: 53 4d 5f 53 45 45 4b 5f 47 45 3a 20 7b 0a 20 20  SM_SEEK_GE: {.  
c4f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 67            /* Fig
c500: 75 72 65 20 6f 75 74 20 69 66 20 77 65 20 6e 65  ure out if we ne
c510: 65 64 20 74 6f 20 27 73 6b 69 70 27 20 74 68 65  ed to 'skip' the
c520: 20 70 6f 69 6e 74 65 72 20 66 6f 72 77 61 72 64   pointer forward
c530: 20 6f 72 20 6e 6f 74 20 2a 2f 0a 20 20 20 20 20   or not */.     
c540: 20 20 20 20 20 20 20 69 66 28 20 28 72 65 73 3c         if( (res<
c550: 3d 30 20 26 26 20 28 70 50 74 72 2d 3e 65 54 79  =0 && (pPtr->eTy
c560: 70 65 20 26 20 4c 53 4d 5f 53 54 41 52 54 5f 44  pe & LSM_START_D
c570: 45 4c 45 54 45 29 29 20 0a 20 20 20 20 20 20 20  ELETE)) .       
c580: 20 20 20 20 20 20 7c 7c 20 28 72 65 73 3e 30 20        || (res>0 
c590: 20 26 26 20 28 70 50 74 72 2d 3e 65 54 79 70 65   && (pPtr->eType
c5a0: 20 26 20 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45 54   & LSM_END_DELET
c5b0: 45 29 29 20 0a 20 20 20 20 20 20 20 20 20 20 20  E)) .           
c5c0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
c5d0: 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74    rc = segmentPt
c5e0: 72 46 77 64 50 6f 69 6e 74 65 72 28 70 43 73 72  rFwdPointer(pCsr
c5f0: 2c 20 70 50 74 72 2c 20 26 69 50 74 72 4f 75 74  , pPtr, &iPtrOut
c600: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d  );.            }
c610: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28  .            if(
c620: 20 72 65 73 3c 30 20 26 26 20 72 63 3d 3d 4c 53   res<0 && rc==LS
c630: 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  M_OK ){.        
c640: 20 20 20 20 20 20 72 63 20 3d 20 73 65 67 6d 65        rc = segme
c650: 6e 74 50 74 72 41 64 76 61 6e 63 65 28 70 43 73  ntPtrAdvance(pCs
c660: 72 2c 20 70 50 74 72 2c 20 30 29 3b 0a 20 20 20  r, pPtr, 0);.   
c670: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
c680: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
c690: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
c6a0: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
c6b0: 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 65  }..    /* If the
c6c0: 20 63 75 72 73 6f 72 20 73 65 65 6b 20 68 61 73   cursor seek has
c6d0: 20 66 6f 75 6e 64 20 61 20 73 65 70 61 72 61 74   found a separat
c6e0: 6f 72 20 6b 65 79 2c 20 61 6e 64 20 74 68 69 73  or key, and this
c6f0: 20 63 75 72 73 6f 72 20 69 73 0a 20 20 20 20 2a   cursor is.    *
c700: 2a 20 73 75 70 70 6f 73 65 64 20 74 6f 20 69 67  * supposed to ig
c710: 6e 6f 72 65 20 73 65 70 61 72 61 74 6f 72 73 20  nore separators 
c720: 6b 65 79 73 2c 20 61 64 76 61 6e 63 65 20 74 6f  keys, advance to
c730: 20 74 68 65 20 6e 65 78 74 20 65 6e 74 72 79 2e   the next entry.
c740: 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d    */.    if( rc=
c750: 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 50 74 72 2d  =LSM_OK && pPtr-
c760: 3e 70 50 67 0a 20 20 20 20 20 26 26 20 73 65 67  >pPg.     && seg
c770: 6d 65 6e 74 50 74 72 49 67 6e 6f 72 65 53 65 70  mentPtrIgnoreSep
c780: 61 72 61 74 6f 72 73 28 70 43 73 72 2c 20 70 50  arators(pCsr, pP
c790: 74 72 29 20 0a 20 20 20 20 20 26 26 20 72 74 49  tr) .     && rtI
c7a0: 73 53 65 70 61 72 61 74 6f 72 28 70 50 74 72 2d  sSeparator(pPtr-
c7b0: 3e 65 54 79 70 65 29 0a 20 20 20 20 29 7b 0a 20  >eType).    ){. 
c7c0: 20 20 20 20 20 61 73 73 65 72 74 28 20 65 53 65       assert( eSe
c7d0: 65 6b 21 3d 4c 53 4d 5f 53 45 45 4b 5f 45 51 20  ek!=LSM_SEEK_EQ 
c7e0: 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 65  );.      rc = se
c7f0: 67 6d 65 6e 74 50 74 72 41 64 76 61 6e 63 65 28  gmentPtrAdvance(
c800: 70 43 73 72 2c 20 70 50 74 72 2c 20 65 53 65 65  pCsr, pPtr, eSee
c810: 6b 3d 3d 4c 53 4d 5f 53 45 45 4b 5f 4c 45 29 3b  k==LSM_SEEK_LE);
c820: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 61 73  .    }.  }..  as
c830: 73 65 72 74 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b  sert( rc!=LSM_OK
c840: 20 7c 7c 20 61 73 73 65 72 74 53 65 65 6b 52 65   || assertSeekRe
c850: 73 75 6c 74 28 70 43 73 72 2c 70 50 74 72 2c 69  sult(pCsr,pPtr,i
c860: 54 6f 70 69 63 2c 70 4b 65 79 2c 6e 4b 65 79 2c  Topic,pKey,nKey,
c870: 65 53 65 65 6b 29 20 29 3b 0a 20 20 2a 70 69 50  eSeek) );.  *piP
c880: 74 72 20 3d 20 28 69 6e 74 29 69 50 74 72 4f 75  tr = (int)iPtrOu
c890: 74 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  t;.  return rc;.
c8a0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  }..static int se
c8b0: 65 6b 49 6e 42 74 72 65 65 28 0a 20 20 4d 75 6c  ekInBtree(.  Mul
c8c0: 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  tiCursor *pCsr, 
c8d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c8e0: 4d 75 6c 74 69 2d 63 75 72 73 6f 72 20 6f 62 6a  Multi-cursor obj
c8f0: 65 63 74 20 2a 2f 0a 20 20 53 65 67 6d 65 6e 74  ect */.  Segment
c900: 20 2a 70 53 65 67 2c 20 20 20 20 20 20 20 20 20   *pSeg,         
c910: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 65 6b           /* Seek
c920: 20 77 69 74 68 69 6e 20 74 68 69 73 20 73 65 67   within this seg
c930: 6d 65 6e 74 20 2a 2f 0a 20 20 69 6e 74 20 69 54  ment */.  int iT
c940: 6f 70 69 63 2c 0a 20 20 76 6f 69 64 20 2a 70 4b  opic,.  void *pK
c950: 65 79 2c 20 69 6e 74 20 6e 4b 65 79 2c 20 20 20  ey, int nKey,   
c960: 20 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 20 74          /* Key t
c970: 6f 20 73 65 65 6b 20 74 6f 20 2a 2f 0a 20 20 4c  o seek to */.  L
c980: 73 6d 50 67 6e 6f 20 2a 61 50 67 2c 20 20 20 20  smPgno *aPg,    
c990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c9a0: 2a 20 4f 55 54 3a 20 50 61 67 65 20 6e 75 6d 62  * OUT: Page numb
c9b0: 65 72 73 20 2a 2f 0a 20 20 50 61 67 65 20 2a 2a  ers */.  Page **
c9c0: 70 70 50 67 20 20 20 20 20 20 20 20 20 20 20 20  ppPg            
c9d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
c9e0: 20 4c 65 61 66 20 28 73 6f 72 74 65 64 2d 72 75   Leaf (sorted-ru
c9f0: 6e 29 20 70 61 67 65 20 72 65 66 65 72 65 6e 63  n) page referenc
ca00: 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 20  e */.){.  int i 
ca10: 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  = 0;.  int rc;. 
ca20: 20 69 6e 74 20 69 50 67 3b 0a 20 20 50 61 67 65   int iPg;.  Page
ca30: 20 2a 70 50 67 20 3d 20 30 3b 0a 20 20 4c 73 6d   *pPg = 0;.  Lsm
ca40: 42 6c 6f 62 20 62 6c 6f 62 20 3d 20 7b 30 2c 20  Blob blob = {0, 
ca50: 30 2c 20 30 7d 3b 0a 0a 20 20 69 50 67 20 3d 20  0, 0};..  iPg = 
ca60: 28 69 6e 74 29 70 53 65 67 2d 3e 69 52 6f 6f 74  (int)pSeg->iRoot
ca70: 3b 0a 20 20 64 6f 20 7b 0a 20 20 20 20 4c 73 6d  ;.  do {.    Lsm
ca80: 50 67 6e 6f 20 2a 70 69 46 69 72 73 74 20 3d 20  Pgno *piFirst = 
ca90: 30 3b 0a 20 20 20 20 69 66 28 20 61 50 67 20 29  0;.    if( aPg )
caa0: 7b 0a 20 20 20 20 20 20 61 50 67 5b 69 2b 2b 5d  {.      aPg[i++]
cab0: 20 3d 20 69 50 67 3b 0a 20 20 20 20 20 20 70 69   = iPg;.      pi
cac0: 46 69 72 73 74 20 3d 20 26 61 50 67 5b 69 5d 3b  First = &aPg[i];
cad0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 63 20 3d  .    }..    rc =
cae0: 20 6c 73 6d 46 73 44 62 50 61 67 65 47 65 74 28   lsmFsDbPageGet(
caf0: 70 43 73 72 2d 3e 70 44 62 2d 3e 70 46 53 2c 20  pCsr->pDb->pFS, 
cb00: 70 53 65 67 2c 20 69 50 67 2c 20 26 70 50 67 29  pSeg, iPg, &pPg)
cb10: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63  ;.    assert( rc
cb20: 3d 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 70 50 67 3d  ==LSM_OK || pPg=
cb30: 3d 30 20 29 3b 0a 20 20 20 20 69 66 28 20 72 63  =0 );.    if( rc
cb40: 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20  ==LSM_OK ){.    
cb50: 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20 20 20    u8 *aData;    
cb60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
cb70: 20 42 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69   Buffer containi
cb80: 6e 67 20 70 61 67 65 20 64 61 74 61 20 2a 2f 0a  ng page data */.
cb90: 20 20 20 20 20 20 69 6e 74 20 6e 44 61 74 61 3b        int nData;
cba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cbb0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 44 61    /* Size of aDa
cbc0: 74 61 5b 5d 20 69 6e 20 62 79 74 65 73 20 2a 2f  ta[] in bytes */
cbd0: 0a 20 20 20 20 20 20 69 6e 74 20 69 4d 69 6e 3b  .      int iMin;
cbe0: 0a 20 20 20 20 20 20 69 6e 74 20 69 4d 61 78 3b  .      int iMax;
cbf0: 0a 20 20 20 20 20 20 69 6e 74 20 6e 52 65 63 3b  .      int nRec;
cc00: 0a 20 20 20 20 20 20 69 6e 74 20 66 6c 61 67 73  .      int flags
cc10: 3b 0a 0a 20 20 20 20 20 20 61 44 61 74 61 20 3d  ;..      aData =
cc20: 20 66 73 50 61 67 65 44 61 74 61 28 70 50 67 2c   fsPageData(pPg,
cc30: 20 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20   &nData);.      
cc40: 66 6c 61 67 73 20 3d 20 70 61 67 65 47 65 74 46  flags = pageGetF
cc50: 6c 61 67 73 28 61 44 61 74 61 2c 20 6e 44 61 74  lags(aData, nDat
cc60: 61 29 3b 0a 20 20 20 20 20 20 69 66 28 20 28 66  a);.      if( (f
cc70: 6c 61 67 73 20 26 20 53 45 47 4d 45 4e 54 5f 42  lags & SEGMENT_B
cc80: 54 52 45 45 5f 46 4c 41 47 29 3d 3d 30 20 29 20  TREE_FLAG)==0 ) 
cc90: 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 69 50  break;..      iP
cca0: 67 20 3d 20 28 69 6e 74 29 70 61 67 65 47 65 74  g = (int)pageGet
ccb0: 50 74 72 28 61 44 61 74 61 2c 20 6e 44 61 74 61  Ptr(aData, nData
ccc0: 29 3b 0a 20 20 20 20 20 20 6e 52 65 63 20 3d 20  );.      nRec = 
ccd0: 70 61 67 65 47 65 74 4e 52 65 63 28 61 44 61 74  pageGetNRec(aDat
cce0: 61 2c 20 6e 44 61 74 61 29 3b 0a 0a 20 20 20 20  a, nData);..    
ccf0: 20 20 69 4d 69 6e 20 3d 20 30 3b 0a 20 20 20 20    iMin = 0;.    
cd00: 20 20 69 4d 61 78 20 3d 20 6e 52 65 63 2d 31 3b    iMax = nRec-1;
cd10: 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 69 4d  .      while( iM
cd20: 61 78 3e 3d 69 4d 69 6e 20 29 7b 0a 20 20 20 20  ax>=iMin ){.    
cd30: 20 20 20 20 69 6e 74 20 69 54 72 79 20 3d 20 28      int iTry = (
cd40: 69 4d 69 6e 2b 69 4d 61 78 29 2f 32 3b 0a 20 20  iMin+iMax)/2;.  
cd50: 20 20 20 20 20 20 76 6f 69 64 20 2a 70 4b 65 79        void *pKey
cd60: 54 3b 20 69 6e 74 20 6e 4b 65 79 54 3b 20 20 20  T; int nKeyT;   
cd70: 20 20 20 20 2f 2a 20 4b 65 79 20 66 6f 72 20 63      /* Key for c
cd80: 65 6c 6c 20 69 54 72 79 20 2a 2f 0a 20 20 20 20  ell iTry */.    
cd90: 20 20 20 20 69 6e 74 20 69 54 6f 70 69 63 54 3b      int iTopicT;
cda0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cdb0: 20 20 2f 2a 20 54 6f 70 69 63 20 66 6f 72 20 6b    /* Topic for k
cdc0: 65 79 20 70 4b 65 79 54 2f 6e 4b 65 79 54 20 2a  ey pKeyT/nKeyT *
cdd0: 2f 0a 20 20 20 20 20 20 20 20 4c 73 6d 50 67 6e  /.        LsmPgn
cde0: 6f 20 69 50 74 72 3b 20 20 20 20 20 20 20 20 20  o iPtr;         
cdf0: 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
ce00: 65 72 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  er associated wi
ce10: 74 68 20 63 65 6c 6c 20 69 54 72 79 20 2a 2f 0a  th cell iTry */.
ce20: 20 20 20 20 20 20 20 20 69 6e 74 20 72 65 73 3b          int res;
ce30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ce40: 20 20 20 20 20 20 2f 2a 20 28 70 4b 65 79 20 2d        /* (pKey -
ce50: 20 70 4b 65 79 54 29 20 2a 2f 0a 0a 20 20 20 20   pKeyT) */..    
ce60: 20 20 20 20 72 63 20 3d 20 70 61 67 65 47 65 74      rc = pageGet
ce70: 42 74 72 65 65 4b 65 79 28 0a 20 20 20 20 20 20  BtreeKey(.      
ce80: 20 20 20 20 20 20 70 53 65 67 2c 20 70 50 67 2c        pSeg, pPg,
ce90: 20 69 54 72 79 2c 20 26 69 50 74 72 2c 20 26 69   iTry, &iPtr, &i
cea0: 54 6f 70 69 63 54 2c 20 26 70 4b 65 79 54 2c 20  TopicT, &pKeyT, 
ceb0: 26 6e 4b 65 79 54 2c 20 26 62 6c 6f 62 0a 20 20  &nKeyT, &blob.  
cec0: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20        );.       
ced0: 20 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20   if( rc!=LSM_OK 
cee0: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20  ) break;.       
cef0: 20 69 66 28 20 70 69 46 69 72 73 74 20 26 26 20   if( piFirst && 
cf00: 70 4b 65 79 54 3d 3d 62 6c 6f 62 2e 70 44 61 74  pKeyT==blob.pDat
cf10: 61 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2a  a ){.          *
cf20: 70 69 46 69 72 73 74 20 3d 20 70 61 67 65 47 65  piFirst = pageGe
cf30: 74 42 74 72 65 65 52 65 66 28 70 50 67 2c 20 69  tBtreeRef(pPg, i
cf40: 54 72 79 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Try);.          
cf50: 70 69 46 69 72 73 74 20 3d 20 30 3b 0a 20 20 20  piFirst = 0;.   
cf60: 20 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20         i++;.    
cf70: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 72      }..        r
cf80: 65 73 20 3d 20 73 6f 72 74 65 64 4b 65 79 43 6f  es = sortedKeyCo
cf90: 6d 70 61 72 65 28 0a 20 20 20 20 20 20 20 20 20  mpare(.         
cfa0: 20 20 20 70 43 73 72 2d 3e 70 44 62 2d 3e 78 43     pCsr->pDb->xC
cfb0: 6d 70 2c 20 69 54 6f 70 69 63 2c 20 70 4b 65 79  mp, iTopic, pKey
cfc0: 2c 20 6e 4b 65 79 2c 20 69 54 6f 70 69 63 54 2c  , nKey, iTopicT,
cfd0: 20 70 4b 65 79 54 2c 20 6e 4b 65 79 54 0a 20 20   pKeyT, nKeyT.  
cfe0: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20        );.       
cff0: 20 69 66 28 20 72 65 73 3c 30 20 29 7b 0a 20 20   if( res<0 ){.  
d000: 20 20 20 20 20 20 20 20 69 50 67 20 3d 20 28 69          iPg = (i
d010: 6e 74 29 69 50 74 72 3b 0a 20 20 20 20 20 20 20  nt)iPtr;.       
d020: 20 20 20 69 4d 61 78 20 3d 20 69 54 72 79 2d 31     iMax = iTry-1
d030: 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b  ;.        }else{
d040: 0a 20 20 20 20 20 20 20 20 20 20 69 4d 69 6e 20  .          iMin 
d050: 3d 20 69 54 72 79 2b 31 3b 0a 20 20 20 20 20 20  = iTry+1;.      
d060: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
d070: 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61    lsmFsPageRelea
d080: 73 65 28 70 50 67 29 3b 0a 20 20 20 20 20 20 70  se(pPg);.      p
d090: 50 67 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20  Pg = 0;.    }.  
d0a0: 7d 77 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f  }while( rc==LSM_
d0b0: 4f 4b 20 29 3b 0a 0a 20 20 73 6f 72 74 65 64 42  OK );..  sortedB
d0c0: 6c 6f 62 46 72 65 65 28 26 62 6c 6f 62 29 3b 0a  lobFree(&blob);.
d0d0: 20 20 61 73 73 65 72 74 28 20 28 72 63 3d 3d 4c    assert( (rc==L
d0e0: 53 4d 5f 4f 4b 29 3d 3d 28 70 50 67 21 3d 30 29  SM_OK)==(pPg!=0)
d0f0: 20 29 3b 0a 20 20 69 66 28 20 70 70 50 67 20 29   );.  if( ppPg )
d100: 7b 0a 20 20 20 20 2a 70 70 50 67 20 3d 20 70 50  {.    *ppPg = pP
d110: 67 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  g;.  }else{.    
d120: 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61 73 65  lsmFsPageRelease
d130: 28 70 50 67 29 3b 0a 20 20 7d 0a 20 20 72 65 74  (pPg);.  }.  ret
d140: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69  urn rc;.}..stati
d150: 63 20 69 6e 74 20 73 65 65 6b 49 6e 53 65 67 6d  c int seekInSegm
d160: 65 6e 74 28 0a 20 20 4d 75 6c 74 69 43 75 72 73  ent(.  MultiCurs
d170: 6f 72 20 2a 70 43 73 72 2c 20 0a 20 20 53 65 67  or *pCsr, .  Seg
d180: 6d 65 6e 74 50 74 72 20 2a 70 50 74 72 2c 0a 20  mentPtr *pPtr,. 
d190: 20 69 6e 74 20 69 54 6f 70 69 63 2c 0a 20 20 76   int iTopic,.  v
d1a0: 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e  oid *pKey, int n
d1b0: 4b 65 79 2c 0a 20 20 69 6e 74 20 69 50 67 2c 20  Key,.  int iPg, 
d1c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d1d0: 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 74         /* Page t
d1e0: 6f 20 73 65 61 72 63 68 20 2a 2f 0a 20 20 69 6e  o search */.  in
d1f0: 74 20 65 53 65 65 6b 2c 20 20 20 20 20 20 20 20  t eSeek,        
d200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d210: 20 53 65 61 72 63 68 20 62 69 61 73 20 2d 20 73   Search bias - s
d220: 65 65 20 61 62 6f 76 65 20 2a 2f 0a 20 20 69 6e  ee above */.  in
d230: 74 20 2a 70 69 50 74 72 2c 20 20 20 20 20 20 20  t *piPtr,       
d240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d250: 20 4f 55 54 3a 20 46 43 20 70 6f 69 6e 74 65 72   OUT: FC pointer
d260: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 62 53 74 6f   */.  int *pbSto
d270: 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p               
d280: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 74        /* OUT: St
d290: 6f 70 20 73 65 61 72 63 68 20 66 6c 61 67 20 2a  op search flag *
d2a0: 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 50 74 72 20  /.){.  int iPtr 
d2b0: 3d 20 69 50 67 3b 0a 20 20 69 6e 74 20 72 63 20  = iPg;.  int rc 
d2c0: 3d 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20 20 69 66 28  = LSM_OK;..  if(
d2d0: 20 70 50 74 72 2d 3e 70 53 65 67 2d 3e 69 52 6f   pPtr->pSeg->iRo
d2e0: 6f 74 20 29 7b 0a 20 20 20 20 50 61 67 65 20 2a  ot ){.    Page *
d2f0: 70 50 67 3b 0a 20 20 20 20 61 73 73 65 72 74 28  pPg;.    assert(
d300: 20 70 50 74 72 2d 3e 70 53 65 67 2d 3e 69 52 6f   pPtr->pSeg->iRo
d310: 6f 74 21 3d 30 20 29 3b 0a 20 20 20 20 72 63 20  ot!=0 );.    rc 
d320: 3d 20 73 65 65 6b 49 6e 42 74 72 65 65 28 70 43  = seekInBtree(pC
d330: 73 72 2c 20 70 50 74 72 2d 3e 70 53 65 67 2c 20  sr, pPtr->pSeg, 
d340: 69 54 6f 70 69 63 2c 20 70 4b 65 79 2c 20 6e 4b  iTopic, pKey, nK
d350: 65 79 2c 20 30 2c 20 26 70 50 67 29 3b 0a 20 20  ey, 0, &pPg);.  
d360: 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
d370: 20 29 20 73 65 67 6d 65 6e 74 50 74 72 53 65 74   ) segmentPtrSet
d380: 50 61 67 65 28 70 50 74 72 2c 20 70 50 67 29 3b  Page(pPtr, pPg);
d390: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66  .  }else{.    if
d3a0: 28 20 69 50 74 72 3d 3d 30 20 29 7b 0a 20 20 20  ( iPtr==0 ){.   
d3b0: 20 20 20 69 50 74 72 20 3d 20 28 69 6e 74 29 70     iPtr = (int)p
d3c0: 50 74 72 2d 3e 70 53 65 67 2d 3e 69 46 69 72 73  Ptr->pSeg->iFirs
d3d0: 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  t;.    }.    if(
d3e0: 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20   rc==LSM_OK ){. 
d3f0: 20 20 20 20 20 72 63 20 3d 20 73 65 67 6d 65 6e       rc = segmen
d400: 74 50 74 72 4c 6f 61 64 50 61 67 65 28 70 43 73  tPtrLoadPage(pCs
d410: 72 2d 3e 70 44 62 2d 3e 70 46 53 2c 20 70 50 74  r->pDb->pFS, pPt
d420: 72 2c 20 69 50 74 72 29 3b 0a 20 20 20 20 7d 0a  r, iPtr);.    }.
d430: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c    }..  if( rc==L
d440: 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  SM_OK ){.    rc 
d450: 3d 20 73 65 67 6d 65 6e 74 50 74 72 53 65 65 6b  = segmentPtrSeek
d460: 28 70 43 73 72 2c 20 70 50 74 72 2c 20 69 54 6f  (pCsr, pPtr, iTo
d470: 70 69 63 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 2c  pic, pKey, nKey,
d480: 20 65 53 65 65 6b 2c 20 70 69 50 74 72 2c 20 70   eSeek, piPtr, p
d490: 62 53 74 6f 70 29 3b 0a 20 20 7d 0a 20 20 72 65  bStop);.  }.  re
d4a0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
d4b0: 2a 20 53 65 65 6b 20 65 61 63 68 20 73 65 67 6d  * Seek each segm
d4c0: 65 6e 74 20 70 6f 69 6e 74 65 72 20 69 6e 20 74  ent pointer in t
d4d0: 68 65 20 61 72 72 61 79 20 6f 66 20 28 70 4c 76  he array of (pLv
d4e0: 6c 2d 3e 6e 52 69 67 68 74 2b 31 29 20 61 74 20  l->nRight+1) at 
d4f0: 61 50 74 72 5b 5d 2e 0a 2a 2a 0a 2a 2a 20 70 62  aPtr[]..**.** pb
d500: 53 74 6f 70 3a 0a 2a 2a 20 20 20 54 68 69 73 20  Stop:.**   This 
d510: 70 61 72 61 6d 65 74 65 72 20 69 73 20 6f 6e 6c  parameter is onl
d520: 79 20 73 69 67 6e 69 66 69 63 61 6e 74 20 69 66  y significant if
d530: 20 70 61 72 61 6d 65 74 65 72 20 65 53 65 65 6b   parameter eSeek
d540: 20 69 73 20 73 65 74 20 74 6f 0a 2a 2a 20 20 20   is set to.**   
d550: 4c 53 4d 5f 53 45 45 4b 5f 45 51 2e 20 49 6e 20  LSM_SEEK_EQ. In 
d560: 74 68 69 73 20 63 61 73 65 2c 20 69 74 20 69 73  this case, it is
d570: 20 73 65 74 20 74 6f 20 74 72 75 65 20 62 65 66   set to true bef
d580: 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 20 69 66  ore returning if
d590: 0a 2a 2a 20 20 20 74 68 65 20 73 65 65 6b 20 6f  .**   the seek o
d5a0: 70 65 72 61 74 69 6f 6e 20 69 73 20 66 69 6e 69  peration is fini
d5b0: 73 68 65 64 2e 20 54 68 69 73 20 63 61 6e 20 68  shed. This can h
d5c0: 61 70 70 65 6e 20 69 6e 20 74 77 6f 20 77 61 79  appen in two way
d5d0: 73 3a 0a 2a 2a 20 20 20 0a 2a 2a 20 20 20 20 20  s:.**   .**     
d5e0: 61 29 20 41 20 6b 65 79 20 6d 61 74 63 68 69 6e  a) A key matchin
d5f0: 67 20 28 70 4b 65 79 2f 6e 4b 65 79 29 20 69 73  g (pKey/nKey) is
d600: 20 66 6f 75 6e 64 2c 20 6f 72 0a 2a 2a 20 20 20   found, or.**   
d610: 20 20 62 29 20 41 20 70 6f 69 6e 74 2d 64 65 6c    b) A point-del
d620: 65 74 65 20 6f 72 20 72 61 6e 67 65 2d 64 65 6c  ete or range-del
d630: 65 74 65 20 64 65 6c 65 74 69 6e 67 20 74 68 65  ete deleting the
d640: 20 6b 65 79 20 69 73 20 66 6f 75 6e 64 2e 0a 2a   key is found..*
d650: 2a 0a 2a 2a 20 20 20 49 6e 20 63 61 73 65 20 28  *.**   In case (
d660: 61 29 2c 20 74 68 65 20 6d 75 6c 74 69 2d 63 75  a), the multi-cu
d670: 72 73 6f 72 20 43 55 52 53 4f 52 5f 53 45 45 4b  rsor CURSOR_SEEK
d680: 5f 45 51 20 66 6c 61 67 20 69 73 20 73 65 74 20  _EQ flag is set 
d690: 61 6e 64 20 74 68 65 20 70 43 73 72 2d 3e 6b 65  and the pCsr->ke
d6a0: 79 0a 2a 2a 20 20 20 61 6e 64 20 70 43 73 72 2d  y.**   and pCsr-
d6b0: 3e 76 61 6c 20 62 6c 6f 62 73 20 70 6f 70 75 6c  >val blobs popul
d6c0: 61 74 65 64 20 62 65 66 6f 72 65 20 72 65 74 75  ated before retu
d6d0: 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  rning..*/.static
d6e0: 20 69 6e 74 20 73 65 65 6b 49 6e 4c 65 76 65 6c   int seekInLevel
d6f0: 28 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  (.  MultiCursor 
d700: 2a 70 43 73 72 2c 20 20 20 20 20 20 20 20 20 20  *pCsr,          
d710: 20 20 20 20 2f 2a 20 53 6f 72 74 65 64 20 63 75      /* Sorted cu
d720: 72 73 6f 72 20 6f 62 6a 65 63 74 20 74 6f 20 73  rsor object to s
d730: 65 65 6b 20 2a 2f 0a 20 20 53 65 67 6d 65 6e 74  eek */.  Segment
d740: 50 74 72 20 2a 61 50 74 72 2c 20 20 20 20 20 20  Ptr *aPtr,      
d750: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
d760: 74 65 72 20 74 6f 20 61 72 72 61 79 20 6f 66 20  ter to array of 
d770: 28 6e 52 68 73 2b 31 29 20 53 50 73 20 2a 2f 0a  (nRhs+1) SPs */.
d780: 20 20 69 6e 74 20 65 53 65 65 6b 2c 20 20 20 20    int eSeek,    
d790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d7a0: 20 20 2f 2a 20 53 65 61 72 63 68 20 62 69 61 73    /* Search bias
d7b0: 20 2d 20 73 65 65 20 61 62 6f 76 65 20 2a 2f 0a   - see above */.
d7c0: 20 20 69 6e 74 20 69 54 6f 70 69 63 2c 20 20 20    int iTopic,   
d7d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d7e0: 20 20 2f 2a 20 4b 65 79 20 74 6f 70 69 63 20 74    /* Key topic t
d7f0: 6f 20 73 65 61 72 63 68 20 66 6f 72 20 2a 2f 0a  o search for */.
d800: 20 20 76 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e    void *pKey, in
d810: 74 20 6e 4b 65 79 2c 20 20 20 20 20 20 20 20 20  t nKey,         
d820: 20 20 2f 2a 20 4b 65 79 20 74 6f 20 73 65 61 72    /* Key to sear
d830: 63 68 20 66 6f 72 20 2a 2f 0a 20 20 4c 73 6d 50  ch for */.  LsmP
d840: 67 6e 6f 20 2a 70 69 50 67 6e 6f 2c 20 20 20 20  gno *piPgno,    
d850: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
d860: 4e 2f 4f 55 54 3a 20 66 72 61 63 74 69 6f 6e 20  N/OUT: fraction 
d870: 63 61 73 63 61 64 65 20 70 6f 69 6e 74 65 72 20  cascade pointer 
d880: 28 6f 72 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20  (or 0) */.  int 
d890: 2a 70 62 53 74 6f 70 20 20 20 20 20 20 20 20 20  *pbStop         
d8a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
d8b0: 55 54 3a 20 53 65 65 20 61 62 6f 76 65 20 2a 2f  UT: See above */
d8c0: 0a 29 7b 0a 20 20 4c 65 76 65 6c 20 2a 70 4c 76  .){.  Level *pLv
d8d0: 6c 20 3d 20 61 50 74 72 5b 30 5d 2e 70 4c 65 76  l = aPtr[0].pLev
d8e0: 65 6c 3b 20 20 20 2f 2a 20 4c 65 76 65 6c 20 74  el;   /* Level t
d8f0: 6f 20 73 65 65 6b 20 77 69 74 68 69 6e 20 2a 2f  o seek within */
d900: 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f  .  int rc = LSM_
d910: 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
d920: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
d930: 65 20 2a 2f 0a 20 20 69 6e 74 20 69 4f 75 74 20  e */.  int iOut 
d940: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
d950: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
d960: 72 20 74 6f 20 72 65 74 75 72 6e 20 74 6f 20 63  r to return to c
d970: 61 6c 6c 65 72 20 2a 2f 0a 20 20 69 6e 74 20 72  aller */.  int r
d980: 65 73 20 3d 20 2d 31 3b 20 20 20 20 20 20 20 20  es = -1;        
d990: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
d9a0: 73 75 6c 74 20 6f 66 20 78 43 6d 70 28 70 4b 65  sult of xCmp(pKe
d9b0: 79 2c 20 73 70 6c 69 74 29 20 2a 2f 0a 20 20 69  y, split) */.  i
d9c0: 6e 74 20 6e 52 68 73 20 3d 20 70 4c 76 6c 2d 3e  nt nRhs = pLvl->
d9d0: 6e 52 69 67 68 74 3b 20 20 20 20 20 20 20 20 2f  nRight;        /
d9e0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 72 69 67 68  * Number of righ
d9f0: 74 2d 68 61 6e 64 2d 73 69 64 65 20 73 65 67 6d  t-hand-side segm
da00: 65 6e 74 73 20 2a 2f 0a 20 20 69 6e 74 20 62 53  ents */.  int bS
da10: 74 6f 70 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 49  top = 0;..  /* I
da20: 66 20 74 68 69 73 20 69 73 20 61 20 63 6f 6d 70  f this is a comp
da30: 6f 73 69 74 65 20 6c 65 76 65 6c 20 28 6f 6e 65  osite level (one
da40: 20 63 75 72 72 65 6e 74 6c 79 20 75 6e 64 65 72   currently under
da50: 67 6f 69 6e 67 20 61 6e 20 69 6e 63 72 65 6d 65  going an increme
da60: 6e 74 61 6c 0a 20 20 2a 2a 20 6d 65 72 67 65 29  ntal.  ** merge)
da70: 2c 20 66 69 67 75 72 65 20 6f 75 74 20 69 66 20  , figure out if 
da80: 74 68 65 20 73 65 61 72 63 68 20 6b 65 79 20 69  the search key i
da90: 73 20 6c 61 72 67 65 72 20 6f 72 20 73 6d 61 6c  s larger or smal
daa0: 6c 65 72 20 74 68 61 6e 20 74 68 65 0a 20 20 2a  ler than the.  *
dab0: 2a 20 6c 65 76 65 6c 73 20 73 70 6c 69 74 2d 6b  * levels split-k
dac0: 65 79 2e 20 20 2a 2f 0a 20 20 69 66 28 20 6e 52  ey.  */.  if( nR
dad0: 68 73 20 29 7b 0a 20 20 20 20 72 65 73 20 3d 20  hs ){.    res = 
dae0: 73 6f 72 74 65 64 4b 65 79 43 6f 6d 70 61 72 65  sortedKeyCompare
daf0: 28 70 43 73 72 2d 3e 70 44 62 2d 3e 78 43 6d 70  (pCsr->pDb->xCmp
db00: 2c 20 69 54 6f 70 69 63 2c 20 70 4b 65 79 2c 20  , iTopic, pKey, 
db10: 6e 4b 65 79 2c 20 0a 20 20 20 20 20 20 20 20 70  nKey, .        p
db20: 4c 76 6c 2d 3e 69 53 70 6c 69 74 54 6f 70 69 63  Lvl->iSplitTopic
db30: 2c 20 70 4c 76 6c 2d 3e 70 53 70 6c 69 74 4b 65  , pLvl->pSplitKe
db40: 79 2c 20 70 4c 76 6c 2d 3e 6e 53 70 6c 69 74 4b  y, pLvl->nSplitK
db50: 65 79 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20  ey.    );.  }.. 
db60: 20 2f 2a 20 49 66 20 28 72 65 73 3c 30 29 2c 20   /* If (res<0), 
db70: 74 68 65 6e 20 6b 65 79 20 70 4b 65 79 2f 6e 4b  then key pKey/nK
db80: 65 79 20 69 73 20 73 6d 61 6c 6c 65 72 20 74 68  ey is smaller th
db90: 61 6e 20 74 68 65 20 73 70 6c 69 74 2d 6b 65 79  an the split-key
dba0: 20 28 6f 72 20 74 68 69 73 0a 20 20 2a 2a 20 69   (or this.  ** i
dbb0: 73 20 6e 6f 74 20 61 20 63 6f 6d 70 6f 73 69 74  s not a composit
dbc0: 65 20 6c 65 76 65 6c 20 61 6e 64 20 74 68 65 72  e level and ther
dbd0: 65 20 69 73 20 6e 6f 20 73 70 6c 69 74 2d 6b 65  e is no split-ke
dbe0: 79 29 2e 20 53 65 61 72 63 68 20 74 68 65 20 0a  y). Search the .
dbf0: 20 20 2a 2a 20 6c 65 66 74 2d 68 61 6e 64 2d 73    ** left-hand-s
dc00: 69 64 65 20 6f 66 20 74 68 65 20 6c 65 76 65 6c  ide of the level
dc10: 20 69 6e 20 74 68 69 73 20 63 61 73 65 2e 20 20   in this case.  
dc20: 2a 2f 0a 20 20 69 66 28 20 72 65 73 3c 30 20 29  */.  if( res<0 )
dc30: 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  {.    int i;.   
dc40: 20 69 6e 74 20 69 50 74 72 20 3d 20 30 3b 0a 20   int iPtr = 0;. 
dc50: 20 20 20 69 66 28 20 6e 52 68 73 3d 3d 30 20 29     if( nRhs==0 )
dc60: 20 69 50 74 72 20 3d 20 28 69 6e 74 29 2a 70 69   iPtr = (int)*pi
dc70: 50 67 6e 6f 3b 0a 0a 20 20 20 20 72 63 20 3d 20  Pgno;..    rc = 
dc80: 73 65 65 6b 49 6e 53 65 67 6d 65 6e 74 28 0a 20  seekInSegment(. 
dc90: 20 20 20 20 20 20 20 70 43 73 72 2c 20 26 61 50         pCsr, &aP
dca0: 74 72 5b 30 5d 2c 20 69 54 6f 70 69 63 2c 20 70  tr[0], iTopic, p
dcb0: 4b 65 79 2c 20 6e 4b 65 79 2c 20 69 50 74 72 2c  Key, nKey, iPtr,
dcc0: 20 65 53 65 65 6b 2c 20 26 69 4f 75 74 2c 20 26   eSeek, &iOut, &
dcd0: 62 53 74 6f 70 0a 20 20 20 20 29 3b 0a 20 20 20  bStop.    );.   
dce0: 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
dcf0: 26 26 20 6e 52 68 73 3e 30 20 26 26 20 65 53 65  && nRhs>0 && eSe
dd00: 65 6b 3d 3d 4c 53 4d 5f 53 45 45 4b 5f 47 45 20  ek==LSM_SEEK_GE 
dd10: 26 26 20 61 50 74 72 5b 30 5d 2e 70 50 67 3d 3d  && aPtr[0].pPg==
dd20: 30 20 29 7b 0a 20 20 20 20 20 20 72 65 73 20 3d  0 ){.      res =
dd30: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f   0;.    }.    fo
dd40: 72 28 69 3d 31 3b 20 69 3c 3d 6e 52 68 73 3b 20  r(i=1; i<=nRhs; 
dd50: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 65 67 6d  i++){.      segm
dd60: 65 6e 74 50 74 72 52 65 73 65 74 28 26 61 50 74  entPtrReset(&aPt
dd70: 72 5b 69 5d 2c 20 4c 53 4d 5f 53 45 47 4d 45 4e  r[i], LSM_SEGMEN
dd80: 54 50 54 52 5f 46 52 45 45 5f 54 48 52 45 53 48  TPTR_FREE_THRESH
dd90: 4f 4c 44 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  OLD);.    }.  }.
dda0: 20 20 0a 20 20 69 66 28 20 72 65 73 3e 3d 30 20    .  if( res>=0 
ddb0: 29 7b 0a 20 20 20 20 69 6e 74 20 62 48 69 74 20  ){.    int bHit 
ddc0: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
ddd0: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
dde0: 61 74 20 6c 65 61 73 74 20 6f 6e 65 20 72 68 73  at least one rhs
ddf0: 20 69 73 20 6e 6f 74 20 45 4f 46 20 2a 2f 0a 20   is not EOF */. 
de00: 20 20 20 69 6e 74 20 69 50 74 72 20 3d 20 28 69     int iPtr = (i
de10: 6e 74 29 2a 70 69 50 67 6e 6f 3b 0a 20 20 20 20  nt)*piPgno;.    
de20: 69 6e 74 20 69 3b 0a 20 20 20 20 73 65 67 6d 65  int i;.    segme
de30: 6e 74 50 74 72 52 65 73 65 74 28 26 61 50 74 72  ntPtrReset(&aPtr
de40: 5b 30 5d 2c 20 4c 53 4d 5f 53 45 47 4d 45 4e 54  [0], LSM_SEGMENT
de50: 50 54 52 5f 46 52 45 45 5f 54 48 52 45 53 48 4f  PTR_FREE_THRESHO
de60: 4c 44 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31  LD);.    for(i=1
de70: 3b 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20  ; rc==LSM_OK && 
de80: 69 3c 3d 6e 52 68 73 20 26 26 20 62 53 74 6f 70  i<=nRhs && bStop
de90: 3d 3d 30 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  ==0; i++){.     
dea0: 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74   SegmentPtr *pPt
deb0: 72 20 3d 20 26 61 50 74 72 5b 69 5d 3b 0a 20 20  r = &aPtr[i];.  
dec0: 20 20 20 20 69 4f 75 74 20 3d 20 30 3b 0a 20 20      iOut = 0;.  
ded0: 20 20 20 20 72 63 20 3d 20 73 65 65 6b 49 6e 53      rc = seekInS
dee0: 65 67 6d 65 6e 74 28 0a 20 20 20 20 20 20 20 20  egment(.        
def0: 20 20 70 43 73 72 2c 20 70 50 74 72 2c 20 69 54    pCsr, pPtr, iT
df00: 6f 70 69 63 2c 20 70 4b 65 79 2c 20 6e 4b 65 79  opic, pKey, nKey
df10: 2c 20 69 50 74 72 2c 20 65 53 65 65 6b 2c 20 26  , iPtr, eSeek, &
df20: 69 4f 75 74 2c 20 26 62 53 74 6f 70 0a 20 20 20  iOut, &bStop.   
df30: 20 20 20 29 3b 0a 20 20 20 20 20 20 69 50 74 72     );.      iPtr
df40: 20 3d 20 69 4f 75 74 3b 0a 0a 20 20 20 20 20 20   = iOut;..      
df50: 2f 2a 20 49 66 20 74 68 65 20 73 65 67 6d 65 6e  /* If the segmen
df60: 74 2d 70 6f 69 6e 74 65 72 20 68 61 73 20 73 65  t-pointer has se
df70: 74 74 6c 65 64 20 6f 6e 20 61 20 6b 65 79 20 74  ttled on a key t
df80: 68 61 74 20 69 73 20 73 6d 61 6c 6c 65 72 20 74  hat is smaller t
df90: 68 61 6e 0a 20 20 20 20 20 20 2a 2a 20 74 68 65  han.      ** the
dfa0: 20 73 70 6c 69 74 6b 65 79 2c 20 69 6e 76 61 6c   splitkey, inval
dfb0: 69 64 61 74 65 20 74 68 65 20 73 65 67 6d 65 6e  idate the segmen
dfc0: 74 2d 70 6f 69 6e 74 65 72 2e 20 20 2a 2f 0a 20  t-pointer.  */. 
dfd0: 20 20 20 20 20 69 66 28 20 70 50 74 72 2d 3e 70       if( pPtr->p
dfe0: 50 67 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65  Pg ){.        re
dff0: 73 20 3d 20 73 6f 72 74 65 64 4b 65 79 43 6f 6d  s = sortedKeyCom
e000: 70 61 72 65 28 70 43 73 72 2d 3e 70 44 62 2d 3e  pare(pCsr->pDb->
e010: 78 43 6d 70 2c 20 0a 20 20 20 20 20 20 20 20 20  xCmp, .         
e020: 20 20 20 72 74 54 6f 70 69 63 28 70 50 74 72 2d     rtTopic(pPtr-
e030: 3e 65 54 79 70 65 29 2c 20 70 50 74 72 2d 3e 70  >eType), pPtr->p
e040: 4b 65 79 2c 20 70 50 74 72 2d 3e 6e 4b 65 79 2c  Key, pPtr->nKey,
e050: 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 4c   .            pL
e060: 76 6c 2d 3e 69 53 70 6c 69 74 54 6f 70 69 63 2c  vl->iSplitTopic,
e070: 20 70 4c 76 6c 2d 3e 70 53 70 6c 69 74 4b 65 79   pLvl->pSplitKey
e080: 2c 20 70 4c 76 6c 2d 3e 6e 53 70 6c 69 74 4b 65  , pLvl->nSplitKe
e090: 79 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20  y.        );.   
e0a0: 20 20 20 20 20 69 66 28 20 72 65 73 3c 30 20 29       if( res<0 )
e0b0: 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  {.          if( 
e0c0: 70 50 74 72 2d 3e 65 54 79 70 65 20 26 20 4c 53  pPtr->eType & LS
e0d0: 4d 5f 53 54 41 52 54 5f 44 45 4c 45 54 45 20 29  M_START_DELETE )
e0e0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 50  {.            pP
e0f0: 74 72 2d 3e 65 54 79 70 65 20 26 3d 20 7e 4c 53  tr->eType &= ~LS
e100: 4d 5f 49 4e 53 45 52 54 3b 0a 20 20 20 20 20 20  M_INSERT;.      
e110: 20 20 20 20 20 20 70 50 74 72 2d 3e 70 4b 65 79        pPtr->pKey
e120: 20 3d 20 70 4c 76 6c 2d 3e 70 53 70 6c 69 74 4b   = pLvl->pSplitK
e130: 65 79 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  ey;.            
e140: 70 50 74 72 2d 3e 6e 4b 65 79 20 3d 20 70 4c 76  pPtr->nKey = pLv
e150: 6c 2d 3e 6e 53 70 6c 69 74 4b 65 79 3b 0a 20 20  l->nSplitKey;.  
e160: 20 20 20 20 20 20 20 20 20 20 70 50 74 72 2d 3e            pPtr->
e170: 70 56 61 6c 20 3d 20 30 3b 0a 20 20 20 20 20 20  pVal = 0;.      
e180: 20 20 20 20 20 20 70 50 74 72 2d 3e 6e 56 61 6c        pPtr->nVal
e190: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20   = 0;.          
e1a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20  }else{.         
e1b0: 20 20 20 73 65 67 6d 65 6e 74 50 74 72 52 65 73     segmentPtrRes
e1c0: 65 74 28 70 50 74 72 2c 20 4c 53 4d 5f 53 45 47  et(pPtr, LSM_SEG
e1d0: 4d 45 4e 54 50 54 52 5f 46 52 45 45 5f 54 48 52  MENTPTR_FREE_THR
e1e0: 45 53 48 4f 4c 44 29 3b 0a 20 20 20 20 20 20 20  ESHOLD);.       
e1f0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20     }.        }. 
e200: 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 69 66       }..      if
e210: 28 20 61 50 74 72 5b 69 5d 2e 70 4b 65 79 20 29  ( aPtr[i].pKey )
e220: 20 62 48 69 74 20 3d 20 31 3b 0a 20 20 20 20 7d   bHit = 1;.    }
e230: 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53  ..    if( rc==LS
e240: 4d 5f 4f 4b 20 26 26 20 65 53 65 65 6b 3d 3d 4c  M_OK && eSeek==L
e250: 53 4d 5f 53 45 45 4b 5f 4c 45 20 26 26 20 62 48  SM_SEEK_LE && bH
e260: 69 74 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72  it==0 ){.      r
e270: 63 20 3d 20 73 65 67 6d 65 6e 74 50 74 72 45 6e  c = segmentPtrEn
e280: 64 28 70 43 73 72 2c 20 26 61 50 74 72 5b 30 5d  d(pCsr, &aPtr[0]
e290: 2c 20 31 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  , 1);.    }.  }.
e2a0: 0a 20 20 61 73 73 65 72 74 28 20 65 53 65 65 6b  .  assert( eSeek
e2b0: 3d 3d 4c 53 4d 5f 53 45 45 4b 5f 45 51 20 7c 7c  ==LSM_SEEK_EQ ||
e2c0: 20 62 53 74 6f 70 3d 3d 30 20 29 3b 0a 20 20 2a   bStop==0 );.  *
e2d0: 70 69 50 67 6e 6f 20 3d 20 69 4f 75 74 3b 0a 20  piPgno = iOut;. 
e2e0: 20 2a 70 62 53 74 6f 70 20 3d 20 62 53 74 6f 70   *pbStop = bStop
e2f0: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
e300: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 75  ..static void mu
e310: 6c 74 69 43 75 72 73 6f 72 47 65 74 4b 65 79 28  ltiCursorGetKey(
e320: 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a  .  MultiCursor *
e330: 70 43 73 72 2c 20 0a 20 20 69 6e 74 20 69 4b 65  pCsr, .  int iKe
e340: 79 2c 0a 20 20 69 6e 74 20 2a 70 65 54 79 70 65  y,.  int *peType
e350: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
e360: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4b 65 79       /* OUT: Key
e370: 20 74 79 70 65 20 28 53 4f 52 54 45 44 5f 57 52   type (SORTED_WR
e380: 49 54 45 20 65 74 63 2e 29 20 2a 2f 0a 20 20 76  ITE etc.) */.  v
e390: 6f 69 64 20 2a 2a 70 70 4b 65 79 2c 20 20 20 20  oid **ppKey,    
e3a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e3b0: 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20 74  * OUT: Pointer t
e3c0: 6f 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e  o buffer contain
e3d0: 69 6e 67 20 6b 65 79 20 2a 2f 0a 20 20 69 6e 74  ing key */.  int
e3e0: 20 2a 70 6e 4b 65 79 20 20 20 20 20 20 20 20 20   *pnKey         
e3f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e400: 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 2a 70 70  OUT: Size of *pp
e410: 4b 65 79 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  Key in bytes */.
e420: 29 7b 0a 20 20 69 6e 74 20 6e 4b 65 79 20 3d 20  ){.  int nKey = 
e430: 30 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 20  0;.  void *pKey 
e440: 3d 20 30 3b 0a 20 20 69 6e 74 20 65 54 79 70 65  = 0;.  int eType
e450: 20 3d 20 30 3b 0a 0a 20 20 73 77 69 74 63 68 28   = 0;..  switch(
e460: 20 69 4b 65 79 20 29 7b 0a 20 20 20 20 63 61 73   iKey ){.    cas
e470: 65 20 43 55 52 53 4f 52 5f 44 41 54 41 5f 54 52  e CURSOR_DATA_TR
e480: 45 45 30 3a 0a 20 20 20 20 63 61 73 65 20 43 55  EE0:.    case CU
e490: 52 53 4f 52 5f 44 41 54 41 5f 54 52 45 45 31 3a  RSOR_DATA_TREE1:
e4a0: 20 7b 0a 20 20 20 20 20 20 54 72 65 65 43 75 72   {.      TreeCur
e4b0: 73 6f 72 20 2a 70 54 72 65 65 43 73 72 20 3d 20  sor *pTreeCsr = 
e4c0: 70 43 73 72 2d 3e 61 70 54 72 65 65 43 73 72 5b  pCsr->apTreeCsr[
e4d0: 69 4b 65 79 2d 43 55 52 53 4f 52 5f 44 41 54 41  iKey-CURSOR_DATA
e4e0: 5f 54 52 45 45 30 5d 3b 0a 20 20 20 20 20 20 69  _TREE0];.      i
e4f0: 66 28 20 6c 73 6d 54 72 65 65 43 75 72 73 6f 72  f( lsmTreeCursor
e500: 56 61 6c 69 64 28 70 54 72 65 65 43 73 72 29 20  Valid(pTreeCsr) 
e510: 29 7b 0a 20 20 20 20 20 20 20 20 6c 73 6d 54 72  ){.        lsmTr
e520: 65 65 43 75 72 73 6f 72 4b 65 79 28 70 54 72 65  eeCursorKey(pTre
e530: 65 43 73 72 2c 20 26 65 54 79 70 65 2c 20 26 70  eCsr, &eType, &p
e540: 4b 65 79 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 20  Key, &nKey);.   
e550: 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b     }.      break
e560: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73  ;.    }..    cas
e570: 65 20 43 55 52 53 4f 52 5f 44 41 54 41 5f 53 59  e CURSOR_DATA_SY
e580: 53 54 45 4d 3a 20 7b 0a 20 20 20 20 20 20 53 6e  STEM: {.      Sn
e590: 61 70 73 68 6f 74 20 2a 70 57 6f 72 6b 65 72 20  apshot *pWorker 
e5a0: 3d 20 70 43 73 72 2d 3e 70 44 62 2d 3e 70 57 6f  = pCsr->pDb->pWo
e5b0: 72 6b 65 72 3b 0a 20 20 20 20 20 20 69 66 28 20  rker;.      if( 
e5c0: 70 57 6f 72 6b 65 72 20 26 26 20 28 70 43 73 72  pWorker && (pCsr
e5d0: 2d 3e 66 6c 61 67 73 20 26 20 43 55 52 53 4f 52  ->flags & CURSOR
e5e0: 5f 46 4c 55 53 48 5f 46 52 45 45 4c 49 53 54 29  _FLUSH_FREELIST)
e5f0: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
e600: 6e 45 6e 74 72 79 20 3d 20 70 57 6f 72 6b 65 72  nEntry = pWorker
e610: 2d 3e 66 72 65 65 6c 69 73 74 2e 6e 45 6e 74 72  ->freelist.nEntr
e620: 79 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  y;.        if( p
e630: 43 73 72 2d 3e 69 46 72 65 65 20 3c 20 28 6e 45  Csr->iFree < (nE
e640: 6e 74 72 79 2a 32 29 20 29 7b 0a 20 20 20 20 20  ntry*2) ){.     
e650: 20 20 20 20 20 46 72 65 65 6c 69 73 74 45 6e 74       FreelistEnt
e660: 72 79 20 2a 61 45 6e 74 72 79 20 3d 20 70 57 6f  ry *aEntry = pWo
e670: 72 6b 65 72 2d 3e 66 72 65 65 6c 69 73 74 2e 61  rker->freelist.a
e680: 45 6e 74 72 79 3b 0a 20 20 20 20 20 20 20 20 20  Entry;.         
e690: 20 69 6e 74 20 69 20 3d 20 6e 45 6e 74 72 79 20   int i = nEntry 
e6a0: 2d 20 31 20 2d 20 28 70 43 73 72 2d 3e 69 46 72  - 1 - (pCsr->iFr
e6b0: 65 65 20 2f 20 32 29 3b 0a 20 20 20 20 20 20 20  ee / 2);.       
e6c0: 20 20 20 75 33 32 20 69 4b 65 79 32 20 3d 20 30     u32 iKey2 = 0
e6d0: 3b 0a 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  ;..          if(
e6e0: 20 28 70 43 73 72 2d 3e 69 46 72 65 65 20 25 20   (pCsr->iFree % 
e6f0: 32 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  2) ){.          
e700: 20 20 65 54 79 70 65 20 3d 20 4c 53 4d 5f 45 4e    eType = LSM_EN
e710: 44 5f 44 45 4c 45 54 45 7c 4c 53 4d 5f 53 59 53  D_DELETE|LSM_SYS
e720: 54 45 4d 4b 45 59 3b 0a 20 20 20 20 20 20 20 20  TEMKEY;.        
e730: 20 20 20 20 69 4b 65 79 32 20 3d 20 61 45 6e 74      iKey2 = aEnt
e740: 72 79 5b 69 5d 2e 69 42 6c 6b 2d 31 3b 0a 20 20  ry[i].iBlk-1;.  
e750: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66          }else if
e760: 28 20 61 45 6e 74 72 79 5b 69 5d 2e 69 49 64 3e  ( aEntry[i].iId>
e770: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
e780: 20 20 65 54 79 70 65 20 3d 20 4c 53 4d 5f 49 4e    eType = LSM_IN
e790: 53 45 52 54 7c 4c 53 4d 5f 53 59 53 54 45 4d 4b  SERT|LSM_SYSTEMK
e7a0: 45 59 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  EY;.            
e7b0: 69 4b 65 79 32 20 3d 20 61 45 6e 74 72 79 5b 69  iKey2 = aEntry[i
e7c0: 5d 2e 69 42 6c 6b 3b 0a 0a 20 20 20 20 20 20 20  ].iBlk;..       
e7d0: 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 69       /* If the i
e7e0: 6e 2d 6d 65 6d 6f 72 79 20 65 6e 74 72 79 20 69  n-memory entry i
e7f0: 6d 6d 65 64 69 61 74 65 6c 79 20 62 65 66 6f 72  mmediately befor
e800: 65 20 74 68 69 73 20 6f 6e 65 20 77 61 73 20 61  e this one was a
e810: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 2a  .             **
e820: 20 44 45 4c 45 54 45 2c 20 61 6e 64 20 74 68 65   DELETE, and the
e830: 20 62 6c 6f 63 6b 20 6e 75 6d 62 65 72 20 69 73   block number is
e840: 20 6f 6e 65 20 67 72 65 61 74 65 72 20 74 68 61   one greater tha
e850: 6e 20 74 68 65 20 63 75 72 72 65 6e 74 0a 20 20  n the current.  
e860: 20 20 20 20 20 20 20 20 20 20 20 2a 2a 20 62 6c             ** bl
e870: 6f 63 6b 20 6e 75 6d 62 65 72 2c 20 6d 61 72 6b  ock number, mark
e880: 20 74 68 69 73 20 65 6e 74 72 79 20 61 73 20 61   this entry as a
e890: 6e 20 22 65 6e 64 2d 64 65 6c 65 74 65 2d 72 61  n "end-delete-ra
e8a0: 6e 67 65 22 2e 20 2a 2f 0a 20 20 20 20 20 20 20  nge". */.       
e8b0: 20 20 20 20 20 69 66 28 20 69 3c 28 6e 45 6e 74       if( i<(nEnt
e8c0: 72 79 2d 31 29 20 26 26 20 61 45 6e 74 72 79 5b  ry-1) && aEntry[
e8d0: 69 2b 31 5d 2e 69 42 6c 6b 3d 3d 69 4b 65 79 32  i+1].iBlk==iKey2
e8e0: 2b 31 20 26 26 20 61 45 6e 74 72 79 5b 69 2b 31  +1 && aEntry[i+1
e8f0: 5d 2e 69 49 64 3c 30 20 29 7b 0a 20 20 20 20 20  ].iId<0 ){.     
e900: 20 20 20 20 20 20 20 20 20 65 54 79 70 65 20 7c           eType |
e910: 3d 20 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45 54 45  = LSM_END_DELETE
e920: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a  ;.            }.
e930: 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65  .          }else
e940: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 54  {.            eT
e950: 79 70 65 20 3d 20 4c 53 4d 5f 53 54 41 52 54 5f  ype = LSM_START_
e960: 44 45 4c 45 54 45 7c 4c 53 4d 5f 53 59 53 54 45  DELETE|LSM_SYSTE
e970: 4d 4b 45 59 3b 0a 20 20 20 20 20 20 20 20 20 20  MKEY;.          
e980: 20 20 69 4b 65 79 32 20 3d 20 61 45 6e 74 72 79    iKey2 = aEntry
e990: 5b 69 5d 2e 69 42 6c 6b 20 2b 20 31 3b 0a 20 20  [i].iBlk + 1;.  
e9a0: 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
e9b0: 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 69       /* If the i
e9c0: 6e 2d 6d 65 6d 6f 72 79 20 65 6e 74 72 79 20 69  n-memory entry i
e9d0: 6d 6d 65 64 69 61 74 65 6c 79 20 61 66 74 65 72  mmediately after
e9e0: 20 74 68 69 73 20 6f 6e 65 20 69 73 20 61 0a 20   this one is a. 
e9f0: 20 20 20 20 20 20 20 20 20 2a 2a 20 44 45 4c 45           ** DELE
ea00: 54 45 2c 20 61 6e 64 20 74 68 65 20 62 6c 6f 63  TE, and the bloc
ea10: 6b 20 6e 75 6d 62 65 72 20 69 73 20 6f 6e 65 20  k number is one 
ea20: 6c 65 73 73 20 74 68 61 6e 20 74 68 65 20 63 75  less than the cu
ea30: 72 72 65 6e 74 0a 20 20 20 20 20 20 20 20 20 20  rrent.          
ea40: 2a 2a 20 6b 65 79 2c 20 6d 61 72 6b 20 74 68 69  ** key, mark thi
ea50: 73 20 65 6e 74 72 79 20 61 73 20 61 6e 20 22 73  s entry as an "s
ea60: 74 61 72 74 2d 64 65 6c 65 74 65 2d 72 61 6e 67  tart-delete-rang
ea70: 65 22 2e 20 20 2a 2f 0a 20 20 20 20 20 20 20 20  e".  */.        
ea80: 20 20 69 66 28 20 69 3e 30 20 26 26 20 61 45 6e    if( i>0 && aEn
ea90: 74 72 79 5b 69 2d 31 5d 2e 69 42 6c 6b 3d 3d 69  try[i-1].iBlk==i
eaa0: 4b 65 79 32 2d 31 20 26 26 20 61 45 6e 74 72 79  Key2-1 && aEntry
eab0: 5b 69 2d 31 5d 2e 69 49 64 3c 30 20 29 7b 0a 20  [i-1].iId<0 ){. 
eac0: 20 20 20 20 20 20 20 20 20 20 20 65 54 79 70 65             eType
ead0: 20 7c 3d 20 4c 53 4d 5f 53 54 41 52 54 5f 44 45   |= LSM_START_DE
eae0: 4c 45 54 45 3b 0a 20 20 20 20 20 20 20 20 20 20  LETE;.          
eaf0: 7d 0a 0a 20 20 20 20 20 20 20 20 20 20 70 4b 65  }..          pKe
eb00: 79 20 3d 20 70 43 73 72 2d 3e 70 53 79 73 74 65  y = pCsr->pSyste
eb10: 6d 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 20 20  mVal;.          
eb20: 6e 4b 65 79 20 3d 20 34 3b 0a 20 20 20 20 20 20  nKey = 4;.      
eb30: 20 20 20 20 6c 73 6d 50 75 74 55 33 32 28 70 4b      lsmPutU32(pK
eb40: 65 79 2c 20 7e 69 4b 65 79 32 29 3b 0a 20 20 20  ey, ~iKey2);.   
eb50: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
eb60: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
eb70: 7d 0a 0a 20 20 20 20 64 65 66 61 75 6c 74 3a 20  }..    default: 
eb80: 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 50 74 72  {.      int iPtr
eb90: 20 3d 20 69 4b 65 79 20 2d 20 43 55 52 53 4f 52   = iKey - CURSOR
eba0: 5f 44 41 54 41 5f 53 45 47 4d 45 4e 54 3b 0a 20  _DATA_SEGMENT;. 
ebb0: 20 20 20 20 20 61 73 73 65 72 74 28 20 69 50 74       assert( iPt
ebc0: 72 3e 3d 30 20 29 3b 0a 20 20 20 20 20 20 69 66  r>=0 );.      if
ebd0: 28 20 69 50 74 72 3d 3d 70 43 73 72 2d 3e 6e 50  ( iPtr==pCsr->nP
ebe0: 74 72 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  tr ){.        if
ebf0: 28 20 70 43 73 72 2d 3e 70 42 74 43 73 72 20 29  ( pCsr->pBtCsr )
ec00: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 4b 65 79  {.          pKey
ec10: 20 3d 20 70 43 73 72 2d 3e 70 42 74 43 73 72 2d   = pCsr->pBtCsr-
ec20: 3e 70 4b 65 79 3b 0a 20 20 20 20 20 20 20 20 20  >pKey;.         
ec30: 20 6e 4b 65 79 20 3d 20 70 43 73 72 2d 3e 70 42   nKey = pCsr->pB
ec40: 74 43 73 72 2d 3e 6e 4b 65 79 3b 0a 20 20 20 20  tCsr->nKey;.    
ec50: 20 20 20 20 20 20 65 54 79 70 65 20 3d 20 70 43        eType = pC
ec60: 73 72 2d 3e 70 42 74 43 73 72 2d 3e 65 54 79 70  sr->pBtCsr->eTyp
ec70: 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  e;.        }.   
ec80: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 69 50 74     }else if( iPt
ec90: 72 3c 70 43 73 72 2d 3e 6e 50 74 72 20 29 7b 0a  r<pCsr->nPtr ){.
eca0: 20 20 20 20 20 20 20 20 53 65 67 6d 65 6e 74 50          SegmentP
ecb0: 74 72 20 2a 70 50 74 72 20 3d 20 26 70 43 73 72  tr *pPtr = &pCsr
ecc0: 2d 3e 61 50 74 72 5b 69 50 74 72 5d 3b 0a 20 20  ->aPtr[iPtr];.  
ecd0: 20 20 20 20 20 20 69 66 28 20 70 50 74 72 2d 3e        if( pPtr->
ece0: 70 50 67 20 29 7b 0a 20 20 20 20 20 20 20 20 20  pPg ){.         
ecf0: 20 70 4b 65 79 20 3d 20 70 50 74 72 2d 3e 70 4b   pKey = pPtr->pK
ed00: 65 79 3b 0a 20 20 20 20 20 20 20 20 20 20 6e 4b  ey;.          nK
ed10: 65 79 20 3d 20 70 50 74 72 2d 3e 6e 4b 65 79 3b  ey = pPtr->nKey;
ed20: 0a 20 20 20 20 20 20 20 20 20 20 65 54 79 70 65  .          eType
ed30: 20 3d 20 70 50 74 72 2d 3e 65 54 79 70 65 3b 0a   = pPtr->eType;.
ed40: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
ed50: 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  }.      break;. 
ed60: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
ed70: 70 65 54 79 70 65 20 29 20 2a 70 65 54 79 70 65  peType ) *peType
ed80: 20 3d 20 65 54 79 70 65 3b 0a 20 20 69 66 28 20   = eType;.  if( 
ed90: 70 6e 4b 65 79 20 29 20 2a 70 6e 4b 65 79 20 3d  pnKey ) *pnKey =
eda0: 20 6e 4b 65 79 3b 0a 20 20 69 66 28 20 70 70 4b   nKey;.  if( ppK
edb0: 65 79 20 29 20 2a 70 70 4b 65 79 20 3d 20 70 4b  ey ) *ppKey = pK
edc0: 65 79 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  ey;.}..static in
edd0: 74 20 73 6f 72 74 65 64 44 62 4b 65 79 43 6f 6d  t sortedDbKeyCom
ede0: 70 61 72 65 28 0a 20 20 4d 75 6c 74 69 43 75 72  pare(.  MultiCur
edf0: 73 6f 72 20 2a 70 43 73 72 2c 0a 20 20 69 6e 74  sor *pCsr,.  int
ee00: 20 69 4c 68 73 46 6c 61 67 73 2c 20 76 6f 69 64   iLhsFlags, void
ee10: 20 2a 70 4c 68 73 4b 65 79 2c 20 69 6e 74 20 6e   *pLhsKey, int n
ee20: 4c 68 73 4b 65 79 2c 0a 20 20 69 6e 74 20 69 52  LhsKey,.  int iR
ee30: 68 73 46 6c 61 67 73 2c 20 76 6f 69 64 20 2a 70  hsFlags, void *p
ee40: 52 68 73 4b 65 79 2c 20 69 6e 74 20 6e 52 68 73  RhsKey, int nRhs
ee50: 4b 65 79 0a 29 7b 0a 20 20 69 6e 74 20 28 2a 78  Key.){.  int (*x
ee60: 43 6d 70 29 28 76 6f 69 64 20 2a 2c 20 69 6e 74  Cmp)(void *, int
ee70: 2c 20 76 6f 69 64 20 2a 2c 20 69 6e 74 29 20 3d  , void *, int) =
ee80: 20 70 43 73 72 2d 3e 70 44 62 2d 3e 78 43 6d 70   pCsr->pDb->xCmp
ee90: 3b 0a 20 20 69 6e 74 20 72 65 73 3b 0a 0a 20 20  ;.  int res;..  
eea0: 2f 2a 20 43 6f 6d 70 61 72 65 20 74 68 65 20 6b  /* Compare the k
eeb0: 65 79 73 2c 20 69 6e 63 6c 75 64 69 6e 67 20 74  eys, including t
eec0: 68 65 20 73 79 73 74 65 6d 20 66 6c 61 67 2e 20  he system flag. 
eed0: 2a 2f 0a 20 20 72 65 73 20 3d 20 73 6f 72 74 65  */.  res = sorte
eee0: 64 4b 65 79 43 6f 6d 70 61 72 65 28 78 43 6d 70  dKeyCompare(xCmp
eef0: 2c 20 0a 20 20 20 20 72 74 54 6f 70 69 63 28 69  , .    rtTopic(i
ef00: 4c 68 73 46 6c 61 67 73 29 2c 20 70 4c 68 73 4b  LhsFlags), pLhsK
ef10: 65 79 2c 20 6e 4c 68 73 4b 65 79 2c 0a 20 20 20  ey, nLhsKey,.   
ef20: 20 72 74 54 6f 70 69 63 28 69 52 68 73 46 6c 61   rtTopic(iRhsFla
ef30: 67 73 29 2c 20 70 52 68 73 4b 65 79 2c 20 6e 52  gs), pRhsKey, nR
ef40: 68 73 4b 65 79 0a 20 20 29 3b 0a 0a 20 20 2f 2a  hsKey.  );..  /*
ef50: 20 49 66 20 61 20 6b 65 79 20 68 61 73 20 74 68   If a key has th
ef60: 65 20 4c 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45  e LSM_START_DELE
ef70: 54 45 20 66 6c 61 67 20 73 65 74 2c 20 62 75 74  TE flag set, but
ef80: 20 6e 6f 74 20 74 68 65 20 4c 53 4d 5f 49 4e 53   not the LSM_INS
ef90: 45 52 54 20 6f 72 0a 20 20 2a 2a 20 4c 53 4d 5f  ERT or.  ** LSM_
efa0: 50 4f 49 4e 54 5f 44 45 4c 45 54 45 20 66 6c 61  POINT_DELETE fla
efb0: 67 73 2c 20 69 74 20 69 73 20 63 6f 6e 73 69 64  gs, it is consid
efc0: 65 72 65 64 20 61 20 64 65 6c 74 61 20 6c 61 72  ered a delta lar
efd0: 67 65 72 2e 20 54 68 69 73 20 70 72 65 76 65 6e  ger. This preven
efe0: 74 73 0a 20 20 2a 2a 20 74 68 65 20 62 65 67 69  ts.  ** the begi
eff0: 6e 6e 69 6e 67 20 6f 66 20 61 6e 20 6f 70 65 6e  nning of an open
f000: 2d 65 6e 64 65 64 20 73 65 74 20 66 72 6f 6d 20  -ended set from 
f010: 6d 61 73 6b 69 6e 67 20 61 20 64 61 74 61 62 61  masking a databa
f020: 73 65 20 65 6e 74 72 79 20 6f 72 0a 20 20 2a 2a  se entry or.  **
f030: 20 64 65 6c 65 74 65 20 61 74 20 61 20 6c 6f 77   delete at a low
f040: 65 72 20 6c 65 76 65 6c 2e 20 20 2a 2f 0a 20 20  er level.  */.  
f050: 69 66 28 20 72 65 73 3d 3d 30 20 26 26 20 28 70  if( res==0 && (p
f060: 43 73 72 2d 3e 66 6c 61 67 73 20 26 20 43 55 52  Csr->flags & CUR
f070: 53 4f 52 5f 49 47 4e 4f 52 45 5f 44 45 4c 45 54  SOR_IGNORE_DELET
f080: 45 29 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20  E) ){.    const 
f090: 69 6e 74 20 6d 20 3d 20 4c 53 4d 5f 50 4f 49 4e  int m = LSM_POIN
f0a0: 54 5f 44 45 4c 45 54 45 7c 4c 53 4d 5f 49 4e 53  T_DELETE|LSM_INS
f0b0: 45 52 54 7c 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45  ERT|LSM_END_DELE
f0c0: 54 45 20 7c 4c 53 4d 5f 53 54 41 52 54 5f 44 45  TE |LSM_START_DE
f0d0: 4c 45 54 45 3b 0a 20 20 20 20 69 6e 74 20 69 44  LETE;.    int iD
f0e0: 65 6c 31 20 3d 20 30 3b 0a 20 20 20 20 69 6e 74  el1 = 0;.    int
f0f0: 20 69 44 65 6c 32 20 3d 20 30 3b 0a 0a 20 20 20   iDel2 = 0;..   
f100: 20 69 66 28 20 4c 53 4d 5f 53 54 41 52 54 5f 44   if( LSM_START_D
f110: 45 4c 45 54 45 3d 3d 28 69 4c 68 73 46 6c 61 67  ELETE==(iLhsFlag
f120: 73 20 26 20 6d 29 20 29 20 69 44 65 6c 31 20 3d  s & m) ) iDel1 =
f130: 20 2b 31 3b 0a 20 20 20 20 69 66 28 20 4c 53 4d   +1;.    if( LSM
f140: 5f 45 4e 44 5f 44 45 4c 45 54 45 20 20 3d 3d 28  _END_DELETE  ==(
f150: 69 4c 68 73 46 6c 61 67 73 20 26 20 6d 29 20 29  iLhsFlags & m) )
f160: 20 69 44 65 6c 31 20 3d 20 2d 31 3b 0a 20 20 20   iDel1 = -1;.   
f170: 20 69 66 28 20 4c 53 4d 5f 53 54 41 52 54 5f 44   if( LSM_START_D
f180: 45 4c 45 54 45 3d 3d 28 69 52 68 73 46 6c 61 67  ELETE==(iRhsFlag
f190: 73 20 26 20 6d 29 20 29 20 69 44 65 6c 32 20 3d  s & m) ) iDel2 =
f1a0: 20 2b 31 3b 0a 20 20 20 20 69 66 28 20 4c 53 4d   +1;.    if( LSM
f1b0: 5f 45 4e 44 5f 44 45 4c 45 54 45 20 20 3d 3d 28  _END_DELETE  ==(
f1c0: 69 52 68 73 46 6c 61 67 73 20 26 20 6d 29 20 29  iRhsFlags & m) )
f1d0: 20 69 44 65 6c 32 20 3d 20 2d 31 3b 0a 0a 20 20   iDel2 = -1;..  
f1e0: 20 20 72 65 73 20 3d 20 28 69 44 65 6c 31 20 2d    res = (iDel1 -
f1f0: 20 69 44 65 6c 32 29 3b 0a 20 20 7d 0a 0a 20 20   iDel2);.  }..  
f200: 72 65 74 75 72 6e 20 72 65 73 3b 0a 7d 0a 0a 73  return res;.}..s
f210: 74 61 74 69 63 20 76 6f 69 64 20 6d 75 6c 74 69  tatic void multi
f220: 43 75 72 73 6f 72 44 6f 43 6f 6d 70 61 72 65 28  CursorDoCompare(
f230: 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73  MultiCursor *pCs
f240: 72 2c 20 69 6e 74 20 69 4f 75 74 2c 20 69 6e 74  r, int iOut, int
f250: 20 62 52 65 76 65 72 73 65 29 7b 0a 20 20 69 6e   bReverse){.  in
f260: 74 20 69 31 3b 0a 20 20 69 6e 74 20 69 32 3b 0a  t i1;.  int i2;.
f270: 20 20 69 6e 74 20 69 52 65 73 3b 0a 20 20 76 6f    int iRes;.  vo
f280: 69 64 20 2a 70 4b 65 79 31 3b 20 69 6e 74 20 6e  id *pKey1; int n
f290: 4b 65 79 31 3b 20 69 6e 74 20 65 54 79 70 65 31  Key1; int eType1
f2a0: 3b 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 32 3b  ;.  void *pKey2;
f2b0: 20 69 6e 74 20 6e 4b 65 79 32 3b 20 69 6e 74 20   int nKey2; int 
f2c0: 65 54 79 70 65 32 3b 0a 20 20 63 6f 6e 73 74 20  eType2;.  const 
f2d0: 69 6e 74 20 6d 75 6c 20 3d 20 28 62 52 65 76 65  int mul = (bReve
f2e0: 72 73 65 20 3f 20 2d 31 20 3a 20 31 29 3b 0a 0a  rse ? -1 : 1);..
f2f0: 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
f300: 61 54 72 65 65 20 26 26 20 69 4f 75 74 3c 70 43  aTree && iOut<pC
f310: 73 72 2d 3e 6e 54 72 65 65 20 29 3b 0a 20 20 69  sr->nTree );.  i
f320: 66 28 20 69 4f 75 74 3e 3d 28 70 43 73 72 2d 3e  f( iOut>=(pCsr->
f330: 6e 54 72 65 65 2f 32 29 20 29 7b 0a 20 20 20 20  nTree/2) ){.    
f340: 69 31 20 3d 20 28 69 4f 75 74 20 2d 20 70 43 73  i1 = (iOut - pCs
f350: 72 2d 3e 6e 54 72 65 65 2f 32 29 20 2a 20 32 3b  r->nTree/2) * 2;
f360: 0a 20 20 20 20 69 32 20 3d 20 69 31 20 2b 20 31  .    i2 = i1 + 1
f370: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  ;.  }else{.    i
f380: 31 20 3d 20 70 43 73 72 2d 3e 61 54 72 65 65 5b  1 = pCsr->aTree[
f390: 69 4f 75 74 2a 32 5d 3b 0a 20 20 20 20 69 32 20  iOut*2];.    i2 
f3a0: 3d 20 70 43 73 72 2d 3e 61 54 72 65 65 5b 69 4f  = pCsr->aTree[iO
f3b0: 75 74 2a 32 2b 31 5d 3b 0a 20 20 7d 0a 0a 20 20  ut*2+1];.  }..  
f3c0: 6d 75 6c 74 69 43 75 72 73 6f 72 47 65 74 4b 65  multiCursorGetKe
f3d0: 79 28 70 43 73 72 2c 20 69 31 2c 20 26 65 54 79  y(pCsr, i1, &eTy
f3e0: 70 65 31 2c 20 26 70 4b 65 79 31 2c 20 26 6e 4b  pe1, &pKey1, &nK
f3f0: 65 79 31 29 3b 0a 20 20 6d 75 6c 74 69 43 75 72  ey1);.  multiCur
f400: 73 6f 72 47 65 74 4b 65 79 28 70 43 73 72 2c 20  sorGetKey(pCsr, 
f410: 69 32 2c 20 26 65 54 79 70 65 32 2c 20 26 70 4b  i2, &eType2, &pK
f420: 65 79 32 2c 20 26 6e 4b 65 79 32 29 3b 0a 0a 20  ey2, &nKey2);.. 
f430: 20 69 66 28 20 70 4b 65 79 31 3d 3d 30 20 29 7b   if( pKey1==0 ){
f440: 0a 20 20 20 20 69 52 65 73 20 3d 20 69 32 3b 0a  .    iRes = i2;.
f450: 20 20 7d 65 6c 73 65 20 69 66 28 20 70 4b 65 79    }else if( pKey
f460: 32 3d 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 73  2==0 ){.    iRes
f470: 20 3d 20 69 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a   = i1;.  }else{.
f480: 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 0a 20 20      int res;..  
f490: 20 20 2f 2a 20 43 6f 6d 70 61 72 65 20 74 68 65    /* Compare the
f4a0: 20 6b 65 79 73 20 2a 2f 0a 20 20 20 20 72 65 73   keys */.    res
f4b0: 20 3d 20 73 6f 72 74 65 64 44 62 4b 65 79 43 6f   = sortedDbKeyCo
f4c0: 6d 70 61 72 65 28 70 43 73 72 2c 0a 20 20 20 20  mpare(pCsr,.    
f4d0: 20 20 20 20 65 54 79 70 65 31 2c 20 70 4b 65 79      eType1, pKey
f4e0: 31 2c 20 6e 4b 65 79 31 2c 20 65 54 79 70 65 32  1, nKey1, eType2
f4f0: 2c 20 70 4b 65 79 32 2c 20 6e 4b 65 79 32 0a 20  , pKey2, nKey2. 
f500: 20 20 20 29 3b 0a 0a 20 20 20 20 72 65 73 20 3d     );..    res =
f510: 20 72 65 73 20 2a 20 6d 75 6c 3b 0a 20 20 20 20   res * mul;.    
f520: 69 66 28 20 72 65 73 3d 3d 30 20 29 7b 0a 20 20  if( res==0 ){.  
f530: 20 20 20 20 2f 2a 20 54 68 65 20 74 77 6f 20 6b      /* The two k
f540: 65 79 73 20 61 72 65 20 69 64 65 6e 74 69 63 61  eys are identica
f550: 6c 2e 20 4e 6f 72 6d 61 6c 6c 79 2c 20 74 68 69  l. Normally, thi
f560: 73 20 6d 65 61 6e 73 20 74 68 61 74 20 74 68 65  s means that the
f570: 20 6b 65 79 20 66 72 6f 6d 0a 20 20 20 20 20 20   key from.      
f580: 2a 2a 20 74 68 65 20 6e 65 77 65 72 20 72 75 6e  ** the newer run
f590: 20 63 6c 6f 62 62 65 72 73 20 74 68 65 20 6f 6c   clobbers the ol
f5a0: 64 2e 20 48 6f 77 65 76 65 72 2c 20 69 66 20 74  d. However, if t
f5b0: 68 65 20 6e 65 77 65 72 20 6b 65 79 20 69 73 20  he newer key is 
f5c0: 61 0a 20 20 20 20 20 20 2a 2a 20 73 65 70 61 72  a.      ** separ
f5d0: 61 74 6f 72 20 6b 65 79 2c 20 6f 72 20 61 20 72  ator key, or a r
f5e0: 61 6e 67 65 2d 64 65 6c 65 74 65 2d 62 6f 75 6e  ange-delete-boun
f5f0: 64 61 72 79 20 6f 6e 6c 79 2c 20 64 6f 20 6e 6f  dary only, do no
f600: 74 20 61 6c 6c 6f 77 20 69 74 0a 20 20 20 20 20  t allow it.     
f610: 20 2a 2a 20 74 6f 20 63 6c 6f 62 62 65 72 20 61   ** to clobber a
f620: 6e 20 6f 6c 64 65 72 20 65 6e 74 72 79 2e 20 20  n older entry.  
f630: 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 63 31  */.      int nc1
f640: 20 3d 20 28 65 54 79 70 65 31 20 26 20 28 4c 53   = (eType1 & (LS
f650: 4d 5f 49 4e 53 45 52 54 7c 4c 53 4d 5f 50 4f 49  M_INSERT|LSM_POI
f660: 4e 54 5f 44 45 4c 45 54 45 29 29 3d 3d 30 3b 0a  NT_DELETE))==0;.
f670: 20 20 20 20 20 20 69 6e 74 20 6e 63 32 20 3d 20        int nc2 = 
f680: 28 65 54 79 70 65 32 20 26 20 28 4c 53 4d 5f 49  (eType2 & (LSM_I
f690: 4e 53 45 52 54 7c 4c 53 4d 5f 50 4f 49 4e 54 5f  NSERT|LSM_POINT_
f6a0: 44 45 4c 45 54 45 29 29 3d 3d 30 3b 0a 20 20 20  DELETE))==0;.   
f6b0: 20 20 20 69 52 65 73 20 3d 20 28 6e 63 31 20 3e     iRes = (nc1 >
f6c0: 20 6e 63 32 29 20 3f 20 69 32 20 3a 20 69 31 3b   nc2) ? i2 : i1;
f6d0: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72  .    }else if( r
f6e0: 65 73 3c 30 20 29 7b 0a 20 20 20 20 20 20 69 52  es<0 ){.      iR
f6f0: 65 73 20 3d 20 69 31 3b 0a 20 20 20 20 7d 65 6c  es = i1;.    }el
f700: 73 65 7b 0a 20 20 20 20 20 20 69 52 65 73 20 3d  se{.      iRes =
f710: 20 69 32 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a   i2;.    }.  }..
f720: 20 20 70 43 73 72 2d 3e 61 54 72 65 65 5b 69 4f    pCsr->aTree[iO
f730: 75 74 5d 20 3d 20 69 52 65 73 3b 0a 7d 0a 0a 2f  ut] = iRes;.}../
f740: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
f750: 6f 6e 20 61 64 76 61 6e 63 65 73 20 73 65 67 6d  on advances segm
f760: 65 6e 74 20 70 6f 69 6e 74 65 72 20 69 50 74 72  ent pointer iPtr
f770: 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 6d 75   belonging to mu
f780: 6c 74 69 2d 63 75 72 73 6f 72 0a 2a 2a 20 70 43  lti-cursor.** pC
f790: 73 72 20 66 6f 72 77 61 72 64 20 28 62 52 65 76  sr forward (bRev
f7a0: 65 72 73 65 3d 3d 30 29 20 6f 72 20 62 61 63 6b  erse==0) or back
f7b0: 77 61 72 64 20 28 62 52 65 76 65 72 73 65 21 3d  ward (bReverse!=
f7c0: 30 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  0)..**.** If the
f7d0: 20 73 65 67 6d 65 6e 74 20 70 6f 69 6e 74 65 72   segment pointer
f7e0: 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 73 65 67   points to a seg
f7f0: 6d 65 6e 74 20 74 68 61 74 20 69 73 20 70 61 72  ment that is par
f800: 74 20 6f 66 20 61 20 63 6f 6d 70 6f 73 69 74 65  t of a composite
f810: 0a 2a 2a 20 6c 65 76 65 6c 2c 20 74 68 65 6e 20  .** level, then 
f820: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 70  the following sp
f830: 65 63 69 61 6c 20 63 61 73 65 20 69 73 20 68 61  ecial case is ha
f840: 6e 64 6c 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 2a  ndled..**.**   *
f850: 20 49 66 20 69 50 74 72 20 69 73 20 74 68 65 20   If iPtr is the 
f860: 6c 68 73 20 6f 66 20 61 20 63 6f 6d 70 6f 73 69  lhs of a composi
f870: 74 65 20 6c 65 76 65 6c 2c 20 61 6e 64 20 74 68  te level, and th
f880: 65 20 63 75 72 73 6f 72 20 69 73 20 62 65 69 6e  e cursor is bein
f890: 67 0a 2a 2a 20 20 20 20 20 61 64 76 61 6e 63 65  g.**     advance
f8a0: 64 20 66 6f 72 77 61 72 64 73 2c 20 61 6e 64 20  d forwards, and 
f8b0: 73 65 67 6d 65 6e 74 20 69 50 74 72 20 69 73 20  segment iPtr is 
f8c0: 61 74 20 45 4f 46 2c 20 6d 6f 76 65 20 61 6c 6c  at EOF, move all
f8d0: 20 70 6f 69 6e 74 65 72 73 0a 2a 2a 20 20 20 20   pointers.**    
f8e0: 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64   that correspond
f8f0: 20 74 6f 20 72 68 73 20 73 65 67 6d 65 6e 74 73   to rhs segments
f900: 20 6f 66 20 74 68 65 20 73 61 6d 65 20 6c 65 76   of the same lev
f910: 65 6c 20 74 6f 20 74 68 65 20 66 69 72 73 74 0a  el to the first.
f920: 2a 2a 20 20 20 20 20 6b 65 79 20 69 6e 20 74 68  **     key in th
f930: 65 69 72 20 72 65 73 70 65 63 74 69 76 65 20 64  eir respective d
f940: 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ata..*/.static i
f950: 6e 74 20 73 65 67 6d 65 6e 74 43 75 72 73 6f 72  nt segmentCursor
f960: 41 64 76 61 6e 63 65 28 0a 20 20 4d 75 6c 74 69  Advance(.  Multi
f970: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 0a 20  Cursor *pCsr, . 
f980: 20 69 6e 74 20 69 50 74 72 2c 0a 20 20 69 6e 74   int iPtr,.  int
f990: 20 62 52 65 76 65 72 73 65 0a 29 7b 0a 20 20 69   bReverse.){.  i
f9a0: 6e 74 20 72 63 3b 0a 20 20 53 65 67 6d 65 6e 74  nt rc;.  Segment
f9b0: 50 74 72 20 2a 70 50 74 72 20 3d 20 26 70 43 73  Ptr *pPtr = &pCs
f9c0: 72 2d 3e 61 50 74 72 5b 69 50 74 72 5d 3b 0a 20  r->aPtr[iPtr];. 
f9d0: 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 20 3d 20 70   Level *pLvl = p
f9e0: 50 74 72 2d 3e 70 4c 65 76 65 6c 3b 0a 20 20 69  Ptr->pLevel;.  i
f9f0: 6e 74 20 62 43 6f 6d 70 6f 73 69 74 65 3b 20 20  nt bComposite;  
fa00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
fa10: 2a 20 54 72 75 65 20 69 66 20 70 50 74 72 20 69  * True if pPtr i
fa20: 73 20 70 61 72 74 20 6f 66 20 63 6f 6d 70 6f 73  s part of compos
fa30: 69 74 65 20 6c 65 76 65 6c 20 2a 2f 0a 0a 20 20  ite level */..  
fa40: 2f 2a 20 41 64 76 61 6e 63 65 20 74 68 65 20 73  /* Advance the s
fa50: 65 67 6d 65 6e 74 2d 70 6f 69 6e 74 65 72 20 6f  egment-pointer o
fa60: 62 6a 65 63 74 2e 20 2a 2f 0a 20 20 72 63 20 3d  bject. */.  rc =
fa70: 20 73 65 67 6d 65 6e 74 50 74 72 41 64 76 61 6e   segmentPtrAdvan
fa80: 63 65 28 70 43 73 72 2c 20 70 50 74 72 2c 20 62  ce(pCsr, pPtr, b
fa90: 52 65 76 65 72 73 65 29 3b 0a 20 20 69 66 28 20  Reverse);.  if( 
faa0: 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65 74  rc!=LSM_OK ) ret
fab0: 75 72 6e 20 72 63 3b 0a 0a 20 20 62 43 6f 6d 70  urn rc;..  bComp
fac0: 6f 73 69 74 65 20 3d 20 28 70 4c 76 6c 2d 3e 6e  osite = (pLvl->n
fad0: 52 69 67 68 74 3e 30 20 26 26 20 70 43 73 72 2d  Right>0 && pCsr-
fae0: 3e 6e 50 74 72 3e 70 4c 76 6c 2d 3e 6e 52 69 67  >nPtr>pLvl->nRig
faf0: 68 74 29 3b 0a 20 20 69 66 28 20 62 43 6f 6d 70  ht);.  if( bComp
fb00: 6f 73 69 74 65 20 26 26 20 70 50 74 72 2d 3e 70  osite && pPtr->p
fb10: 50 67 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74  Pg==0 ){.    int
fb20: 20 62 46 69 78 20 3d 20 30 3b 0a 20 20 20 20 69   bFix = 0;.    i
fb30: 66 28 20 28 62 52 65 76 65 72 73 65 3d 3d 30 29  f( (bReverse==0)
fb40: 3d 3d 28 70 50 74 72 2d 3e 70 53 65 67 3d 3d 26  ==(pPtr->pSeg==&
fb50: 70 4c 76 6c 2d 3e 6c 68 73 29 20 29 7b 0a 20 20  pLvl->lhs) ){.  
fb60: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20      int i;.     
fb70: 20 69 66 28 20 62 52 65 76 65 72 73 65 20 29 7b   if( bReverse ){
fb80: 0a 20 20 20 20 20 20 20 20 53 65 67 6d 65 6e 74  .        Segment
fb90: 50 74 72 20 2a 70 4c 68 73 20 3d 20 26 70 43 73  Ptr *pLhs = &pCs
fba0: 72 2d 3e 61 50 74 72 5b 69 50 74 72 20 2d 20 31  r->aPtr[iPtr - 1
fbb0: 20 2d 20 28 70 50 74 72 2d 3e 70 53 65 67 20 2d   - (pPtr->pSeg -
fbc0: 20 70 4c 76 6c 2d 3e 61 52 68 73 29 5d 3b 0a 20   pLvl->aRhs)];. 
fbd0: 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20         for(i=0; 
fbe0: 69 3c 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 3b 20  i<pLvl->nRight; 
fbf0: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20  i++){.          
fc00: 69 66 28 20 70 4c 68 73 5b 69 2b 31 5d 2e 70 50  if( pLhs[i+1].pP
fc10: 67 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  g ) break;.     
fc20: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 28     }.        if(
fc30: 20 69 3d 3d 70 4c 76 6c 2d 3e 6e 52 69 67 68 74   i==pLvl->nRight
fc40: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 62 46   ){.          bF
fc50: 69 78 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  ix = 1;.        
fc60: 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74    rc = segmentPt
fc70: 72 45 6e 64 28 70 43 73 72 2c 20 70 4c 68 73 2c  rEnd(pCsr, pLhs,
fc80: 20 31 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20   1);.        }. 
fc90: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
fca0: 20 20 20 20 62 46 69 78 20 3d 20 31 3b 0a 20 20      bFix = 1;.  
fcb0: 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 72        for(i=0; r
fcc0: 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 69 3c 70  c==LSM_OK && i<p
fcd0: 4c 76 6c 2d 3e 6e 52 69 67 68 74 3b 20 69 2b 2b  Lvl->nRight; i++
fce0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ){.          rc 
fcf0: 3d 20 73 6f 72 74 65 64 52 68 73 46 69 72 73 74  = sortedRhsFirst
fd00: 28 70 43 73 72 2c 20 70 4c 76 6c 2c 20 26 70 43  (pCsr, pLvl, &pC
fd10: 73 72 2d 3e 61 50 74 72 5b 69 50 74 72 2b 31 2b  sr->aPtr[iPtr+1+
fd20: 69 5d 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  i]);.        }. 
fd30: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
fd40: 20 20 69 66 28 20 62 46 69 78 20 29 7b 0a 20 20    if( bFix ){.  
fd50: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20      int i;.     
fd60: 20 66 6f 72 28 69 3d 70 43 73 72 2d 3e 6e 54 72   for(i=pCsr->nTr
fd70: 65 65 2d 31 3b 20 69 3e 30 3b 20 69 2d 2d 29 7b  ee-1; i>0; i--){
fd80: 0a 20 20 20 20 20 20 20 20 6d 75 6c 74 69 43 75  .        multiCu
fd90: 72 73 6f 72 44 6f 43 6f 6d 70 61 72 65 28 70 43  rsorDoCompare(pC
fda0: 73 72 2c 20 69 2c 20 62 52 65 76 65 72 73 65 29  sr, i, bReverse)
fdb0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
fdc0: 20 20 7d 0a 0a 23 69 66 20 30 0a 20 20 69 66 28    }..#if 0.  if(
fdd0: 20 62 43 6f 6d 70 6f 73 69 74 65 20 26 26 20 70   bComposite && p
fde0: 50 74 72 2d 3e 70 53 65 67 3d 3d 26 70 4c 76 6c  Ptr->pSeg==&pLvl
fdf0: 2d 3e 6c 68 73 20 20 20 20 20 20 20 2f 2a 20 6c  ->lhs       /* l
fe00: 68 73 20 6f 66 20 63 6f 6d 70 6f 73 69 74 65 20  hs of composite 
fe10: 6c 65 76 65 6c 20 2a 2f 0a 20 20 20 26 26 20 62  level */.   && b
fe20: 52 65 76 65 72 73 65 3d 3d 30 20 20 20 20 20 20  Reverse==0      
fe30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fe40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 63 73 72            /* csr
fe50: 20 61 64 76 61 6e 63 65 64 20 66 6f 72 77 61 72   advanced forwar
fe60: 64 73 20 2a 2f 0a 20 20 20 26 26 20 70 50 74 72  ds */.   && pPtr
fe70: 2d 3e 70 50 67 3d 3d 30 20 20 20 20 20 20 20 20  ->pPg==0        
fe80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fe90: 20 20 20 20 20 20 20 2f 2a 20 73 65 67 6d 65 6e         /* segmen
fea0: 74 20 61 74 20 45 4f 46 20 2a 2f 0a 20 20 29 7b  t at EOF */.  ){
feb0: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
fec0: 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 4c 53 4d  for(i=0; rc==LSM
fed0: 5f 4f 4b 20 26 26 20 69 3c 70 4c 76 6c 2d 3e 6e  _OK && i<pLvl->n
fee0: 52 69 67 68 74 3b 20 69 2b 2b 29 7b 0a 20 20 20  Right; i++){.   
fef0: 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64 52 68     rc = sortedRh
ff00: 73 46 69 72 73 74 28 70 43 73 72 2c 20 70 4c 76  sFirst(pCsr, pLv
ff10: 6c 2c 20 26 70 43 73 72 2d 3e 61 50 74 72 5b 69  l, &pCsr->aPtr[i
ff20: 50 74 72 2b 31 2b 69 5d 29 3b 0a 20 20 20 20 7d  Ptr+1+i]);.    }
ff30: 0a 20 20 20 20 66 6f 72 28 69 3d 70 43 73 72 2d  .    for(i=pCsr-
ff40: 3e 6e 54 72 65 65 2d 31 3b 20 69 3e 30 3b 20 69  >nTree-1; i>0; i
ff50: 2d 2d 29 7b 0a 20 20 20 20 20 20 6d 75 6c 74 69  --){.      multi
ff60: 43 75 72 73 6f 72 44 6f 43 6f 6d 70 61 72 65 28  CursorDoCompare(
ff70: 70 43 73 72 2c 20 69 2c 20 30 29 3b 0a 20 20 20  pCsr, i, 0);.   
ff80: 20 7d 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20   }.  }.#endif.. 
ff90: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
ffa0: 74 61 74 69 63 20 76 6f 69 64 20 6d 63 75 72 73  tatic void mcurs
ffb0: 6f 72 46 72 65 65 43 6f 6d 70 6f 6e 65 6e 74 73  orFreeComponents
ffc0: 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43  (MultiCursor *pC
ffd0: 73 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  sr){.  int i;.  
ffe0: 6c 73 6d 5f 65 6e 76 20 2a 70 45 6e 76 20 3d 20  lsm_env *pEnv = 
fff0: 70 43 73 72 2d 3e 70 44 62 2d 3e 70 45 6e 76 3b  pCsr->pDb->pEnv;
10000 0a 0a 20 20 2f 2a 20 43 6c 6f 73 65 20 74 68 65  ..  /* Close the
10010 20 74 72 65 65 20 63 75 72 73 6f 72 2c 20 69 66   tree cursor, if
10020 20 61 6e 79 2e 20 2a 2f 0a 20 20 6c 73 6d 54 72   any. */.  lsmTr
10030 65 65 43 75 72 73 6f 72 44 65 73 74 72 6f 79 28  eeCursorDestroy(
10040 70 43 73 72 2d 3e 61 70 54 72 65 65 43 73 72 5b  pCsr->apTreeCsr[
10050 30 5d 29 3b 0a 20 20 6c 73 6d 54 72 65 65 43 75  0]);.  lsmTreeCu
10060 72 73 6f 72 44 65 73 74 72 6f 79 28 70 43 73 72  rsorDestroy(pCsr
10070 2d 3e 61 70 54 72 65 65 43 73 72 5b 31 5d 29 3b  ->apTreeCsr[1]);
10080 0a 0a 20 20 2f 2a 20 52 65 73 65 74 20 74 68 65  ..  /* Reset the
10090 20 73 65 67 6d 65 6e 74 20 70 6f 69 6e 74 65 72   segment pointer
100a0 73 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  s */.  for(i=0; 
100b0 69 3c 70 43 73 72 2d 3e 6e 50 74 72 3b 20 69 2b  i<pCsr->nPtr; i+
100c0 2b 29 7b 0a 20 20 20 20 73 65 67 6d 65 6e 74 50  +){.    segmentP
100d0 74 72 52 65 73 65 74 28 26 70 43 73 72 2d 3e 61  trReset(&pCsr->a
100e0 50 74 72 5b 69 5d 2c 20 30 29 3b 0a 20 20 7d 0a  Ptr[i], 0);.  }.
100f0 0a 20 20 2f 2a 20 41 6e 64 20 74 68 65 20 62 2d  .  /* And the b-
10100 74 72 65 65 20 63 75 72 73 6f 72 2c 20 69 66 20  tree cursor, if 
10110 61 6e 79 20 2a 2f 0a 20 20 62 74 72 65 65 43 75  any */.  btreeCu
10120 72 73 6f 72 46 72 65 65 28 70 43 73 72 2d 3e 70  rsorFree(pCsr->p
10130 42 74 43 73 72 29 3b 0a 0a 20 20 2f 2a 20 46 72  BtCsr);..  /* Fr
10140 65 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 2a  ee allocations *
10150 2f 0a 20 20 6c 73 6d 46 72 65 65 28 70 45 6e 76  /.  lsmFree(pEnv
10160 2c 20 70 43 73 72 2d 3e 61 50 74 72 29 3b 0a 20  , pCsr->aPtr);. 
10170 20 6c 73 6d 46 72 65 65 28 70 45 6e 76 2c 20 70   lsmFree(pEnv, p
10180 43 73 72 2d 3e 61 54 72 65 65 29 3b 0a 20 20 6c  Csr->aTree);.  l
10190 73 6d 46 72 65 65 28 70 45 6e 76 2c 20 70 43 73  smFree(pEnv, pCs
101a0 72 2d 3e 70 53 79 73 74 65 6d 56 61 6c 29 3b 0a  r->pSystemVal);.
101b0 0a 20 20 2f 2a 20 5a 65 72 6f 20 66 69 65 6c 64  .  /* Zero field
101c0 73 20 2a 2f 0a 20 20 70 43 73 72 2d 3e 6e 50 74  s */.  pCsr->nPt
101d0 72 20 3d 20 30 3b 0a 20 20 70 43 73 72 2d 3e 61  r = 0;.  pCsr->a
101e0 50 74 72 20 3d 20 30 3b 0a 20 20 70 43 73 72 2d  Ptr = 0;.  pCsr-
101f0 3e 6e 54 72 65 65 20 3d 20 30 3b 0a 20 20 70 43  >nTree = 0;.  pC
10200 73 72 2d 3e 61 54 72 65 65 20 3d 20 30 3b 0a 20  sr->aTree = 0;. 
10210 20 70 43 73 72 2d 3e 70 53 79 73 74 65 6d 56 61   pCsr->pSystemVa
10220 6c 20 3d 20 30 3b 0a 20 20 70 43 73 72 2d 3e 61  l = 0;.  pCsr->a
10230 70 54 72 65 65 43 73 72 5b 30 5d 20 3d 20 30 3b  pTreeCsr[0] = 0;
10240 0a 20 20 70 43 73 72 2d 3e 61 70 54 72 65 65 43  .  pCsr->apTreeC
10250 73 72 5b 31 5d 20 3d 20 30 3b 0a 20 20 70 43 73  sr[1] = 0;.  pCs
10260 72 2d 3e 70 42 74 43 73 72 20 3d 20 30 3b 0a 7d  r->pBtCsr = 0;.}
10270 0a 0a 76 6f 69 64 20 6c 73 6d 4d 43 75 72 73 6f  ..void lsmMCurso
10280 72 46 72 65 65 43 61 63 68 65 28 6c 73 6d 5f 64  rFreeCache(lsm_d
10290 62 20 2a 70 44 62 29 7b 0a 20 20 4d 75 6c 74 69  b *pDb){.  Multi
102a0 43 75 72 73 6f 72 20 2a 70 3b 0a 20 20 4d 75 6c  Cursor *p;.  Mul
102b0 74 69 43 75 72 73 6f 72 20 2a 70 4e 65 78 74 3b  tiCursor *pNext;
102c0 0a 20 20 66 6f 72 28 70 3d 70 44 62 2d 3e 70 43  .  for(p=pDb->pC
102d0 73 72 43 61 63 68 65 3b 20 70 3b 20 70 3d 70 4e  srCache; p; p=pN
102e0 65 78 74 29 7b 0a 20 20 20 20 70 4e 65 78 74 20  ext){.    pNext 
102f0 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  = p->pNext;.    
10300 6c 73 6d 4d 43 75 72 73 6f 72 43 6c 6f 73 65 28  lsmMCursorClose(
10310 70 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 70 44 62  p, 0);.  }.  pDb
10320 2d 3e 70 43 73 72 43 61 63 68 65 20 3d 20 30 3b  ->pCsrCache = 0;
10330 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20  .}../*.** Close 
10340 74 68 65 20 63 75 72 73 6f 72 20 70 61 73 73 65  the cursor passe
10350 64 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61  d as the first a
10360 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 49  rgument..**.** I
10370 66 20 74 68 65 20 62 43 61 63 68 65 20 70 61 72  f the bCache par
10380 61 6d 65 74 65 72 20 69 73 20 74 72 75 65 2c 20  ameter is true, 
10390 74 68 65 6e 20 73 68 69 66 74 20 74 68 65 20 63  then shift the c
103a0 75 72 73 6f 72 20 74 6f 20 74 68 65 20 70 43 73  ursor to the pCs
103b0 72 43 61 63 68 65 0a 2a 2a 20 6c 69 73 74 20 66  rCache.** list f
103c0 6f 72 20 70 6f 73 73 69 62 6c 65 20 72 65 75 73  or possible reus
103d0 65 20 69 6e 73 74 65 61 64 20 6f 66 20 61 63 74  e instead of act
103e0 75 61 6c 6c 79 20 64 65 6c 65 74 69 6e 67 20 69  ually deleting i
103f0 74 2e 0a 2a 2f 0a 76 6f 69 64 20 6c 73 6d 4d 43  t..*/.void lsmMC
10400 75 72 73 6f 72 43 6c 6f 73 65 28 4d 75 6c 74 69  ursorClose(Multi
10410 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e  Cursor *pCsr, in
10420 74 20 62 43 61 63 68 65 29 7b 0a 20 20 69 66 28  t bCache){.  if(
10430 20 70 43 73 72 20 29 7b 0a 20 20 20 20 6c 73 6d   pCsr ){.    lsm
10440 5f 64 62 20 2a 70 44 62 20 3d 20 70 43 73 72 2d  _db *pDb = pCsr-
10450 3e 70 44 62 3b 0a 20 20 20 20 4d 75 6c 74 69 43  >pDb;.    MultiC
10460 75 72 73 6f 72 20 2a 2a 70 70 3b 20 20 20 20 20  ursor **pp;     
10470 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61          /* Itera
10480 74 6f 72 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a  tor variable */.
10490 0a 20 20 20 20 2f 2a 20 54 68 65 20 63 75 72 73  .    /* The curs
104a0 6f 72 20 6d 61 79 20 6f 72 20 6d 61 79 20 6e 6f  or may or may no
104b0 74 20 62 65 20 63 75 72 72 65 6e 74 6c 79 20 70  t be currently p
104c0 61 72 74 20 6f 66 20 74 68 65 20 6c 69 6e 6b 65  art of the linke
104d0 64 20 6c 69 73 74 20 0a 20 20 20 20 2a 2a 20 73  d list .    ** s
104e0 74 61 72 74 69 6e 67 20 61 74 20 6c 73 6d 5f 64  tarting at lsm_d
104f0 62 2e 70 43 73 72 2e 20 49 66 20 69 74 20 69 73  b.pCsr. If it is
10500 2c 20 65 78 74 72 61 63 74 20 69 74 2e 20 20 2a  , extract it.  *
10510 2f 0a 20 20 20 20 66 6f 72 28 70 70 3d 26 70 44  /.    for(pp=&pD
10520 62 2d 3e 70 43 73 72 3b 20 2a 70 70 3b 20 70 70  b->pCsr; *pp; pp
10530 3d 26 28 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29  =&((*pp)->pNext)
10540 29 7b 0a 20 20 20 20 20 20 69 66 28 20 2a 70 70  ){.      if( *pp
10550 3d 3d 70 43 73 72 20 29 7b 0a 20 20 20 20 20 20  ==pCsr ){.      
10560 20 20 2a 70 70 20 3d 20 70 43 73 72 2d 3e 70 4e    *pp = pCsr->pN
10570 65 78 74 3b 0a 20 20 20 20 20 20 20 20 62 72 65  ext;.        bre
10580 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
10590 7d 0a 0a 20 20 20 20 69 66 28 20 62 43 61 63 68  }..    if( bCach
105a0 65 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69  e ){.      int i
105b0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
105c0 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
105d0 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
105e0 68 20 73 65 67 6d 65 6e 74 2d 70 6f 69 6e 74 65  h segment-pointe
105f0 72 73 20 2a 2f 0a 0a 20 20 20 20 20 20 2f 2a 20  rs */..      /* 
10600 52 65 6c 65 61 73 65 20 61 6e 79 20 70 61 67 65  Release any page
10610 20 72 65 66 65 72 65 6e 63 65 73 20 68 65 6c 64   references held
10620 20 62 79 20 74 68 69 73 20 63 75 72 73 6f 72 2e   by this cursor.
10630 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74   */.      assert
10640 28 20 21 70 43 73 72 2d 3e 70 42 74 43 73 72 20  ( !pCsr->pBtCsr 
10650 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30  );.      for(i=0
10660 3b 20 69 3c 70 43 73 72 2d 3e 6e 50 74 72 3b 20  ; i<pCsr->nPtr; 
10670 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 53 65  i++){.        Se
10680 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72 20 3d  gmentPtr *pPtr =
10690 20 26 70 43 73 72 2d 3e 61 50 74 72 5b 69 5d 3b   &pCsr->aPtr[i];
106a0 0a 20 20 20 20 20 20 20 20 6c 73 6d 46 73 50 61  .        lsmFsPa
106b0 67 65 52 65 6c 65 61 73 65 28 70 50 74 72 2d 3e  geRelease(pPtr->
106c0 70 50 67 29 3b 0a 20 20 20 20 20 20 20 20 70 50  pPg);.        pP
106d0 74 72 2d 3e 70 50 67 20 3d 20 30 3b 0a 20 20 20  tr->pPg = 0;.   
106e0 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 52     }..      /* R
106f0 65 73 65 74 20 74 68 65 20 74 72 65 65 20 63 75  eset the tree cu
10700 72 73 6f 72 73 20 2a 2f 0a 20 20 20 20 20 20 6c  rsors */.      l
10710 73 6d 54 72 65 65 43 75 72 73 6f 72 52 65 73 65  smTreeCursorRese
10720 74 28 70 43 73 72 2d 3e 61 70 54 72 65 65 43 73  t(pCsr->apTreeCs
10730 72 5b 30 5d 29 3b 0a 20 20 20 20 20 20 6c 73 6d  r[0]);.      lsm
10740 54 72 65 65 43 75 72 73 6f 72 52 65 73 65 74 28  TreeCursorReset(
10750 70 43 73 72 2d 3e 61 70 54 72 65 65 43 73 72 5b  pCsr->apTreeCsr[
10760 31 5d 29 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 41  1]);..      /* A
10770 64 64 20 74 68 65 20 63 75 72 73 6f 72 20 74 6f  dd the cursor to
10780 20 74 68 65 20 70 43 73 72 43 61 63 68 65 20 6c   the pCsrCache l
10790 69 73 74 20 2a 2f 0a 20 20 20 20 20 20 70 43 73  ist */.      pCs
107a0 72 2d 3e 70 4e 65 78 74 20 3d 20 70 44 62 2d 3e  r->pNext = pDb->
107b0 70 43 73 72 43 61 63 68 65 3b 0a 20 20 20 20 20  pCsrCache;.     
107c0 20 70 44 62 2d 3e 70 43 73 72 43 61 63 68 65 20   pDb->pCsrCache 
107d0 3d 20 70 43 73 72 3b 0a 20 20 20 20 7d 65 6c 73  = pCsr;.    }els
107e0 65 7b 0a 20 20 20 20 20 20 2f 2a 20 46 72 65 65  e{.      /* Free
107f0 20 74 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20   the allocation 
10800 75 73 65 64 20 74 6f 20 63 61 63 68 65 20 74 68  used to cache th
10810 65 20 63 75 72 72 65 6e 74 20 6b 65 79 2c 20 69  e current key, i
10820 66 20 61 6e 79 2e 20 2a 2f 0a 20 20 20 20 20 20  f any. */.      
10830 73 6f 72 74 65 64 42 6c 6f 62 46 72 65 65 28 26  sortedBlobFree(&
10840 70 43 73 72 2d 3e 6b 65 79 29 3b 0a 20 20 20 20  pCsr->key);.    
10850 20 20 73 6f 72 74 65 64 42 6c 6f 62 46 72 65 65    sortedBlobFree
10860 28 26 70 43 73 72 2d 3e 76 61 6c 29 3b 0a 0a 20  (&pCsr->val);.. 
10870 20 20 20 20 20 2f 2a 20 46 72 65 65 20 74 68 65       /* Free the
10880 20 63 6f 6d 70 6f 6e 65 6e 74 20 63 75 72 73 6f   component curso
10890 72 73 20 2a 2f 0a 20 20 20 20 20 20 6d 63 75 72  rs */.      mcur
108a0 73 6f 72 46 72 65 65 43 6f 6d 70 6f 6e 65 6e 74  sorFreeComponent
108b0 73 28 70 43 73 72 29 3b 0a 0a 20 20 20 20 20 20  s(pCsr);..      
108c0 2f 2a 20 46 72 65 65 20 74 68 65 20 63 75 72 73  /* Free the curs
108d0 6f 72 20 73 74 72 75 63 74 75 72 65 20 69 74 73  or structure its
108e0 65 6c 66 20 2a 2f 0a 20 20 20 20 20 20 6c 73 6d  elf */.      lsm
108f0 46 72 65 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20  Free(pDb->pEnv, 
10900 70 43 73 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  pCsr);.    }.  }
10910 0a 7d 0a 0a 23 64 65 66 69 6e 65 20 54 52 45 45  .}..#define TREE
10920 5f 4e 4f 4e 45 20 30 0a 23 64 65 66 69 6e 65 20  _NONE 0.#define 
10930 54 52 45 45 5f 4f 4c 44 20 20 31 0a 23 64 65 66  TREE_OLD  1.#def
10940 69 6e 65 20 54 52 45 45 5f 42 4f 54 48 20 32 0a  ine TREE_BOTH 2.
10950 0a 2f 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72  ./*.** Parameter
10960 20 65 54 72 65 65 20 69 73 20 6f 6e 65 20 6f 66   eTree is one of
10970 20 54 52 45 45 5f 4f 4c 44 20 6f 72 20 54 52 45   TREE_OLD or TRE
10980 45 5f 42 4f 54 48 2e 0a 2a 2f 0a 73 74 61 74 69  E_BOTH..*/.stati
10990 63 20 69 6e 74 20 6d 75 6c 74 69 43 75 72 73 6f  c int multiCurso
109a0 72 41 64 64 54 72 65 65 28 4d 75 6c 74 69 43 75  rAddTree(MultiCu
109b0 72 73 6f 72 20 2a 70 43 73 72 2c 20 53 6e 61 70  rsor *pCsr, Snap
109c0 73 68 6f 74 20 2a 70 53 6e 61 70 2c 20 69 6e 74  shot *pSnap, int
109d0 20 65 54 72 65 65 29 7b 0a 20 20 69 6e 74 20 72   eTree){.  int r
109e0 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 6c 73  c = LSM_OK;.  ls
109f0 6d 5f 64 62 20 2a 64 62 20 3d 20 70 43 73 72 2d  m_db *db = pCsr-
10a00 3e 70 44 62 3b 0a 0a 20 20 2f 2a 20 41 64 64 20  >pDb;..  /* Add 
10a10 61 20 74 72 65 65 20 63 75 72 73 6f 72 20 6f 6e  a tree cursor on
10a20 20 74 68 65 20 27 6f 6c 64 27 20 74 72 65 65 2c   the 'old' tree,
10a30 20 69 66 20 69 74 20 65 78 69 73 74 73 2e 20 2a   if it exists. *
10a40 2f 0a 20 20 69 66 28 20 65 54 72 65 65 21 3d 54  /.  if( eTree!=T
10a50 52 45 45 5f 4e 4f 4e 45 20 0a 20 20 20 26 26 20  REE_NONE .   && 
10a60 6c 73 6d 54 72 65 65 48 61 73 4f 6c 64 28 64 62  lsmTreeHasOld(db
10a70 29 20 0a 20 20 20 26 26 20 64 62 2d 3e 74 72 65  ) .   && db->tre
10a80 65 68 64 72 2e 69 4f 6c 64 4c 6f 67 21 3d 70 53  ehdr.iOldLog!=pS
10a90 6e 61 70 2d 3e 69 4c 6f 67 4f 66 66 20 0a 20 20  nap->iLogOff .  
10aa0 29 7b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 54  ){.    rc = lsmT
10ab0 72 65 65 43 75 72 73 6f 72 4e 65 77 28 64 62 2c  reeCursorNew(db,
10ac0 20 31 2c 20 26 70 43 73 72 2d 3e 61 70 54 72 65   1, &pCsr->apTre
10ad0 65 43 73 72 5b 31 5d 29 3b 0a 20 20 7d 0a 0a 20  eCsr[1]);.  }.. 
10ae0 20 2f 2a 20 41 64 64 20 61 20 74 72 65 65 20 63   /* Add a tree c
10af0 75 72 73 6f 72 20 6f 6e 20 74 68 65 20 27 63 75  ursor on the 'cu
10b00 72 72 65 6e 74 27 20 74 72 65 65 2c 20 69 66 20  rrent' tree, if 
10b10 72 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20 20 69  required. */.  i
10b20 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26  f( rc==LSM_OK &&
10b30 20 65 54 72 65 65 3d 3d 54 52 45 45 5f 42 4f 54   eTree==TREE_BOT
10b40 48 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 6c 73  H ){.    rc = ls
10b50 6d 54 72 65 65 43 75 72 73 6f 72 4e 65 77 28 64  mTreeCursorNew(d
10b60 62 2c 20 30 2c 20 26 70 43 73 72 2d 3e 61 70 54  b, 0, &pCsr->apT
10b70 72 65 65 43 73 72 5b 30 5d 29 3b 0a 20 20 7d 0a  reeCsr[0]);.  }.
10b80 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
10b90 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74  .static int mult
10ba0 69 43 75 72 73 6f 72 41 64 64 52 68 73 28 4d 75  iCursorAddRhs(Mu
10bb0 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  ltiCursor *pCsr,
10bc0 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 29 7b 0a 20   Level *pLvl){. 
10bd0 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 6e 52   int i;.  int nR
10be0 68 73 20 3d 20 70 4c 76 6c 2d 3e 6e 52 69 67 68  hs = pLvl->nRigh
10bf0 74 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 4c  t;..  assert( pL
10c00 76 6c 2d 3e 6e 52 69 67 68 74 3e 30 20 29 3b 0a  vl->nRight>0 );.
10c10 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
10c20 61 50 74 72 3d 3d 30 20 29 3b 0a 20 20 70 43 73  aPtr==0 );.  pCs
10c30 72 2d 3e 61 50 74 72 20 3d 20 6c 73 6d 4d 61 6c  r->aPtr = lsmMal
10c40 6c 6f 63 5a 65 72 6f 28 70 43 73 72 2d 3e 70 44  locZero(pCsr->pD
10c50 62 2d 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66 28  b->pEnv, sizeof(
10c60 53 65 67 6d 65 6e 74 50 74 72 29 20 2a 20 6e 52  SegmentPtr) * nR
10c70 68 73 29 3b 0a 20 20 69 66 28 20 21 70 43 73 72  hs);.  if( !pCsr
10c80 2d 3e 61 50 74 72 20 29 20 72 65 74 75 72 6e 20  ->aPtr ) return 
10c90 4c 53 4d 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a  LSM_NOMEM_BKPT;.
10ca0 20 20 70 43 73 72 2d 3e 6e 50 74 72 20 3d 20 6e    pCsr->nPtr = n
10cb0 52 68 73 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b  Rhs;..  for(i=0;
10cc0 20 69 3c 6e 52 68 73 3b 20 69 2b 2b 29 7b 0a 20   i<nRhs; i++){. 
10cd0 20 20 20 70 43 73 72 2d 3e 61 50 74 72 5b 69 5d     pCsr->aPtr[i]
10ce0 2e 70 53 65 67 20 3d 20 26 70 4c 76 6c 2d 3e 61  .pSeg = &pLvl->a
10cf0 52 68 73 5b 69 5d 3b 0a 20 20 20 20 70 43 73 72  Rhs[i];.    pCsr
10d00 2d 3e 61 50 74 72 5b 69 5d 2e 70 4c 65 76 65 6c  ->aPtr[i].pLevel
10d10 20 3d 20 70 4c 76 6c 3b 0a 20 20 7d 0a 0a 20 20   = pLvl;.  }..  
10d20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 7d  return LSM_OK;.}
10d30 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 75  ..static void mu
10d40 6c 74 69 43 75 72 73 6f 72 41 64 64 4f 6e 65 28  ltiCursorAddOne(
10d50 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73  MultiCursor *pCs
10d60 72 2c 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 2c 20  r, Level *pLvl, 
10d70 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 69 66 28  int *pRc){.  if(
10d80 20 2a 70 52 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b   *pRc==LSM_OK ){
10d90 0a 20 20 20 20 69 6e 74 20 69 50 74 72 20 3d 20  .    int iPtr = 
10da0 70 43 73 72 2d 3e 6e 50 74 72 3b 0a 20 20 20 20  pCsr->nPtr;.    
10db0 69 6e 74 20 69 3b 0a 20 20 20 20 70 43 73 72 2d  int i;.    pCsr-
10dc0 3e 61 50 74 72 5b 69 50 74 72 5d 2e 70 4c 65 76  >aPtr[iPtr].pLev
10dd0 65 6c 20 3d 20 70 4c 76 6c 3b 0a 20 20 20 20 70  el = pLvl;.    p
10de0 43 73 72 2d 3e 61 50 74 72 5b 69 50 74 72 5d 2e  Csr->aPtr[iPtr].
10df0 70 53 65 67 20 3d 20 26 70 4c 76 6c 2d 3e 6c 68  pSeg = &pLvl->lh
10e00 73 3b 0a 20 20 20 20 69 50 74 72 2b 2b 3b 0a 20  s;.    iPtr++;. 
10e10 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 4c     for(i=0; i<pL
10e20 76 6c 2d 3e 6e 52 69 67 68 74 3b 20 69 2b 2b 29  vl->nRight; i++)
10e30 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 61 50  {.      pCsr->aP
10e40 74 72 5b 69 50 74 72 5d 2e 70 4c 65 76 65 6c 20  tr[iPtr].pLevel 
10e50 3d 20 70 4c 76 6c 3b 0a 20 20 20 20 20 20 70 43  = pLvl;.      pC
10e60 73 72 2d 3e 61 50 74 72 5b 69 50 74 72 5d 2e 70  sr->aPtr[iPtr].p
10e70 53 65 67 20 3d 20 26 70 4c 76 6c 2d 3e 61 52 68  Seg = &pLvl->aRh
10e80 73 5b 69 5d 3b 0a 20 20 20 20 20 20 69 50 74 72  s[i];.      iPtr
10e90 2b 2b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69  ++;.    }..    i
10ea0 66 28 20 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 20  f( pLvl->nRight 
10eb0 26 26 20 70 4c 76 6c 2d 3e 70 53 70 6c 69 74 4b  && pLvl->pSplitK
10ec0 65 79 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 73  ey==0 ){.      s
10ed0 6f 72 74 65 64 53 70 6c 69 74 6b 65 79 28 70 43  ortedSplitkey(pC
10ee0 73 72 2d 3e 70 44 62 2c 20 70 4c 76 6c 2c 20 70  sr->pDb, pLvl, p
10ef0 52 63 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  Rc);.    }.    p
10f00 43 73 72 2d 3e 6e 50 74 72 20 3d 20 69 50 74 72  Csr->nPtr = iPtr
10f10 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20  ;.  }.}..static 
10f20 69 6e 74 20 6d 75 6c 74 69 43 75 72 73 6f 72 41  int multiCursorA
10f30 64 64 41 6c 6c 28 4d 75 6c 74 69 43 75 72 73 6f  ddAll(MultiCurso
10f40 72 20 2a 70 43 73 72 2c 20 53 6e 61 70 73 68 6f  r *pCsr, Snapsho
10f50 74 20 2a 70 53 6e 61 70 29 7b 0a 20 20 4c 65 76  t *pSnap){.  Lev
10f60 65 6c 20 2a 70 4c 76 6c 3b 0a 20 20 69 6e 74 20  el *pLvl;.  int 
10f70 6e 50 74 72 20 3d 20 30 3b 0a 20 20 69 6e 74 20  nPtr = 0;.  int 
10f80 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20 20  rc = LSM_OK;..  
10f90 66 6f 72 28 70 4c 76 6c 3d 70 53 6e 61 70 2d 3e  for(pLvl=pSnap->
10fa0 70 4c 65 76 65 6c 3b 20 70 4c 76 6c 3b 20 70 4c  pLevel; pLvl; pL
10fb0 76 6c 3d 70 4c 76 6c 2d 3e 70 4e 65 78 74 29 7b  vl=pLvl->pNext){
10fc0 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 4c  .    /* If the L
10fd0 45 56 45 4c 5f 49 4e 43 4f 4d 50 4c 45 54 45 20  EVEL_INCOMPLETE 
10fe0 66 6c 61 67 20 69 73 20 73 65 74 2c 20 74 68 65  flag is set, the
10ff0 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
11000 69 73 20 62 65 69 6e 67 0a 20 20 20 20 2a 2a 20  is being.    ** 
11010 63 61 6c 6c 65 64 20 28 69 6e 64 69 72 65 63 74  called (indirect
11020 6c 79 29 20 66 72 6f 6d 20 77 69 74 68 69 6e 20  ly) from within 
11030 61 20 73 6f 72 74 65 64 4e 65 77 54 6f 70 6c 65  a sortedNewTople
11040 76 65 6c 28 29 20 63 61 6c 6c 20 74 6f 0a 20 20  vel() call to.  
11050 20 20 2a 2a 20 63 6f 6e 73 74 72 75 63 74 20 70    ** construct p
11060 4c 76 6c 2e 20 49 6e 20 74 68 69 73 20 63 61 73  Lvl. In this cas
11070 65 20 69 67 6e 6f 72 65 20 70 4c 76 6c 20 2d 20  e ignore pLvl - 
11080 74 68 69 73 20 63 75 72 73 6f 72 20 69 73 20 67  this cursor is g
11090 6f 69 6e 67 20 74 6f 0a 20 20 20 20 2a 2a 20 62  oing to.    ** b
110a0 65 20 75 73 65 64 20 74 6f 20 72 65 74 72 69 65  e used to retrie
110b0 76 65 20 61 20 66 72 65 65 6c 69 73 74 20 65 6e  ve a freelist en
110c0 74 72 79 20 66 72 6f 6d 20 74 68 65 20 4c 53 4d  try from the LSM
110d0 2c 20 61 6e 64 20 74 68 65 20 70 61 72 74 69 61  , and the partia
110e0 6c 6c 79 0a 20 20 20 20 2a 2a 20 63 6f 6d 70 6c  lly.    ** compl
110f0 65 74 65 20 6c 65 76 65 6c 20 6d 61 79 20 63 6f  ete level may co
11100 6e 66 75 73 65 20 69 74 2e 20 20 2a 2f 0a 20 20  nfuse it.  */.  
11110 20 20 69 66 28 20 70 4c 76 6c 2d 3e 66 6c 61 67    if( pLvl->flag
11120 73 20 26 20 4c 45 56 45 4c 5f 49 4e 43 4f 4d 50  s & LEVEL_INCOMP
11130 4c 45 54 45 20 29 20 63 6f 6e 74 69 6e 75 65 3b  LETE ) continue;
11140 0a 20 20 20 20 6e 50 74 72 20 2b 3d 20 28 31 20  .    nPtr += (1 
11150 2b 20 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 29 3b  + pLvl->nRight);
11160 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20  .  }..  assert( 
11170 70 43 73 72 2d 3e 61 50 74 72 3d 3d 30 20 29 3b  pCsr->aPtr==0 );
11180 0a 20 20 70 43 73 72 2d 3e 61 50 74 72 20 3d 20  .  pCsr->aPtr = 
11190 6c 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28  lsmMallocZeroRc(
111a0 70 43 73 72 2d 3e 70 44 62 2d 3e 70 45 6e 76 2c  pCsr->pDb->pEnv,
111b0 20 73 69 7a 65 6f 66 28 53 65 67 6d 65 6e 74 50   sizeof(SegmentP
111c0 74 72 29 20 2a 20 6e 50 74 72 2c 20 26 72 63 29  tr) * nPtr, &rc)
111d0 3b 0a 0a 20 20 66 6f 72 28 70 4c 76 6c 3d 70 53  ;..  for(pLvl=pS
111e0 6e 61 70 2d 3e 70 4c 65 76 65 6c 3b 20 70 4c 76  nap->pLevel; pLv
111f0 6c 3b 20 70 4c 76 6c 3d 70 4c 76 6c 2d 3e 70 4e  l; pLvl=pLvl->pN
11200 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20 28 70  ext){.    if( (p
11210 4c 76 6c 2d 3e 66 6c 61 67 73 20 26 20 4c 45 56  Lvl->flags & LEV
11220 45 4c 5f 49 4e 43 4f 4d 50 4c 45 54 45 29 3d 3d  EL_INCOMPLETE)==
11230 30 20 29 7b 0a 20 20 20 20 20 20 6d 75 6c 74 69  0 ){.      multi
11240 43 75 72 73 6f 72 41 64 64 4f 6e 65 28 70 43 73  CursorAddOne(pCs
11250 72 2c 20 70 4c 76 6c 2c 20 26 72 63 29 3b 0a 20  r, pLvl, &rc);. 
11260 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
11270 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
11280 20 69 6e 74 20 6d 75 6c 74 69 43 75 72 73 6f 72   int multiCursor
11290 49 6e 69 74 28 4d 75 6c 74 69 43 75 72 73 6f 72  Init(MultiCursor
112a0 20 2a 70 43 73 72 2c 20 53 6e 61 70 73 68 6f 74   *pCsr, Snapshot
112b0 20 2a 70 53 6e 61 70 29 7b 0a 20 20 69 6e 74 20   *pSnap){.  int 
112c0 72 63 3b 0a 20 20 72 63 20 3d 20 6d 75 6c 74 69  rc;.  rc = multi
112d0 43 75 72 73 6f 72 41 64 64 41 6c 6c 28 70 43 73  CursorAddAll(pCs
112e0 72 2c 20 70 53 6e 61 70 29 3b 0a 20 20 69 66 28  r, pSnap);.  if(
112f0 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20   rc==LSM_OK ){. 
11300 20 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75 72     rc = multiCur
11310 73 6f 72 41 64 64 54 72 65 65 28 70 43 73 72 2c  sorAddTree(pCsr,
11320 20 70 53 6e 61 70 2c 20 54 52 45 45 5f 42 4f 54   pSnap, TREE_BOT
11330 48 29 3b 0a 20 20 7d 0a 20 20 70 43 73 72 2d 3e  H);.  }.  pCsr->
11340 66 6c 61 67 73 20 7c 3d 20 28 43 55 52 53 4f 52  flags |= (CURSOR
11350 5f 49 47 4e 4f 52 45 5f 53 59 53 54 45 4d 20 7c  _IGNORE_SYSTEM |
11360 20 43 55 52 53 4f 52 5f 49 47 4e 4f 52 45 5f 44   CURSOR_IGNORE_D
11370 45 4c 45 54 45 29 3b 0a 20 20 72 65 74 75 72 6e  ELETE);.  return
11380 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 4d   rc;.}..static M
11390 75 6c 74 69 43 75 72 73 6f 72 20 2a 6d 75 6c 74  ultiCursor *mult
113a0 69 43 75 72 73 6f 72 4e 65 77 28 6c 73 6d 5f 64  iCursorNew(lsm_d
113b0 62 20 2a 64 62 2c 20 69 6e 74 20 2a 70 52 63 29  b *db, int *pRc)
113c0 7b 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  {.  MultiCursor 
113d0 2a 70 43 73 72 3b 0a 20 20 70 43 73 72 20 3d 20  *pCsr;.  pCsr = 
113e0 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 29 6c  (MultiCursor *)l
113f0 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28 64  smMallocZeroRc(d
11400 62 2d 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66 28  b->pEnv, sizeof(
11410 4d 75 6c 74 69 43 75 72 73 6f 72 29 2c 20 70 52  MultiCursor), pR
11420 63 29 3b 0a 20 20 69 66 28 20 70 43 73 72 20 29  c);.  if( pCsr )
11430 7b 0a 20 20 20 20 70 43 73 72 2d 3e 70 4e 65 78  {.    pCsr->pNex
11440 74 20 3d 20 64 62 2d 3e 70 43 73 72 3b 0a 20 20  t = db->pCsr;.  
11450 20 20 64 62 2d 3e 70 43 73 72 20 3d 20 70 43 73    db->pCsr = pCs
11460 72 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 44 62  r;.    pCsr->pDb
11470 20 3d 20 64 62 3b 0a 20 20 7d 0a 20 20 72 65 74   = db;.  }.  ret
11480 75 72 6e 20 70 43 73 72 3b 0a 7d 0a 0a 0a 76 6f  urn pCsr;.}...vo
11490 69 64 20 6c 73 6d 53 6f 72 74 65 64 52 65 6d 61  id lsmSortedRema
114a0 70 28 6c 73 6d 5f 64 62 20 2a 70 44 62 29 7b 0a  p(lsm_db *pDb){.
114b0 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70    MultiCursor *p
114c0 43 73 72 3b 0a 20 20 66 6f 72 28 70 43 73 72 3d  Csr;.  for(pCsr=
114d0 70 44 62 2d 3e 70 43 73 72 3b 20 70 43 73 72 3b  pDb->pCsr; pCsr;
114e0 20 70 43 73 72 3d 70 43 73 72 2d 3e 70 4e 65 78   pCsr=pCsr->pNex
114f0 74 29 7b 0a 20 20 20 20 69 6e 74 20 69 50 74 72  t){.    int iPtr
11500 3b 0a 20 20 20 20 69 66 28 20 70 43 73 72 2d 3e  ;.    if( pCsr->
11510 70 42 74 43 73 72 20 29 7b 0a 20 20 20 20 20 20  pBtCsr ){.      
11520 62 74 72 65 65 43 75 72 73 6f 72 4c 6f 61 64 4b  btreeCursorLoadK
11530 65 79 28 70 43 73 72 2d 3e 70 42 74 43 73 72 29  ey(pCsr->pBtCsr)
11540 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28  ;.    }.    for(
11550 69 50 74 72 3d 30 3b 20 69 50 74 72 3c 70 43 73  iPtr=0; iPtr<pCs
11560 72 2d 3e 6e 50 74 72 3b 20 69 50 74 72 2b 2b 29  r->nPtr; iPtr++)
11570 7b 0a 20 20 20 20 20 20 73 65 67 6d 65 6e 74 50  {.      segmentP
11580 74 72 4c 6f 61 64 43 65 6c 6c 28 26 70 43 73 72  trLoadCell(&pCsr
11590 2d 3e 61 50 74 72 5b 69 50 74 72 5d 2c 20 70 43  ->aPtr[iPtr], pC
115a0 73 72 2d 3e 61 50 74 72 5b 69 50 74 72 5d 2e 69  sr->aPtr[iPtr].i
115b0 43 65 6c 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  Cell);.    }.  }
115c0 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
115d0 6d 75 6c 74 69 43 75 72 73 6f 72 52 65 61 64 53  multiCursorReadS
115e0 65 70 61 72 61 74 6f 72 73 28 4d 75 6c 74 69 43  eparators(MultiC
115f0 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20  ursor *pCsr){.  
11600 69 66 28 20 70 43 73 72 2d 3e 6e 50 74 72 3e 30  if( pCsr->nPtr>0
11610 20 29 7b 0a 20 20 20 20 70 43 73 72 2d 3e 66 6c   ){.    pCsr->fl
11620 61 67 73 20 7c 3d 20 43 55 52 53 4f 52 5f 52 45  ags |= CURSOR_RE
11630 41 44 5f 53 45 50 41 52 41 54 4f 52 53 3b 0a 20  AD_SEPARATORS;. 
11640 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 48 61 76 65   }.}../*.** Have
11650 20 74 68 69 73 20 63 75 72 73 6f 72 20 73 6b 69   this cursor ski
11660 70 20 6f 76 65 72 20 53 4f 52 54 45 44 5f 44 45  p over SORTED_DE
11670 4c 45 54 45 20 65 6e 74 72 69 65 73 2e 0a 2a 2f  LETE entries..*/
11680 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 75 6c  .static void mul
11690 74 69 43 75 72 73 6f 72 49 67 6e 6f 72 65 44 65  tiCursorIgnoreDe
116a0 6c 65 74 65 28 4d 75 6c 74 69 43 75 72 73 6f 72  lete(MultiCursor
116b0 20 2a 70 43 73 72 29 7b 0a 20 20 69 66 28 20 70   *pCsr){.  if( p
116c0 43 73 72 20 29 20 70 43 73 72 2d 3e 66 6c 61 67  Csr ) pCsr->flag
116d0 73 20 7c 3d 20 43 55 52 53 4f 52 5f 49 47 4e 4f  s |= CURSOR_IGNO
116e0 52 45 5f 44 45 4c 45 54 45 3b 0a 7d 0a 0a 2f 2a  RE_DELETE;.}../*
116f0 0a 2a 2a 20 49 66 20 74 68 65 20 66 72 65 65 2d  .** If the free-
11700 62 6c 6f 63 6b 20 6c 69 73 74 20 69 73 20 6e 6f  block list is no
11710 74 20 65 6d 70 74 79 2c 20 74 68 65 6e 20 68 61  t empty, then ha
11720 76 65 20 74 68 69 73 20 63 75 72 73 6f 72 20 76  ve this cursor v
11730 69 73 69 74 20 61 20 6b 65 79 0a 2a 2a 20 77 69  isit a key.** wi
11740 74 68 20 28 61 29 20 74 68 65 20 73 79 73 74 65  th (a) the syste
11750 6d 20 62 69 74 20 73 65 74 2c 20 61 6e 64 20 28  m bit set, and (
11760 62 29 20 74 68 65 20 6b 65 79 20 22 46 52 45 45  b) the key "FREE
11770 4c 49 53 54 22 20 61 6e 64 20 28 63 29 20 61 20  LIST" and (c) a 
11780 76 61 6c 75 65 20 0a 2a 2a 20 62 6c 6f 62 20 63  value .** blob c
11790 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 73 65  ontaining the se
117a0 72 69 61 6c 69 7a 65 64 20 66 72 65 65 2d 62 6c  rialized free-bl
117b0 6f 63 6b 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61  ock list..*/.sta
117c0 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 43 75 72  tic int multiCur
117d0 73 6f 72 56 69 73 69 74 46 72 65 65 6c 69 73 74  sorVisitFreelist
117e0 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43  (MultiCursor *pC
117f0 73 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  sr){.  int rc = 
11800 4c 53 4d 5f 4f 4b 3b 0a 20 20 70 43 73 72 2d 3e  LSM_OK;.  pCsr->
11810 66 6c 61 67 73 20 7c 3d 20 43 55 52 53 4f 52 5f  flags |= CURSOR_
11820 46 4c 55 53 48 5f 46 52 45 45 4c 49 53 54 3b 0a  FLUSH_FREELIST;.
11830 20 20 70 43 73 72 2d 3e 70 53 79 73 74 65 6d 56    pCsr->pSystemV
11840 61 6c 20 3d 20 6c 73 6d 4d 61 6c 6c 6f 63 52 63  al = lsmMallocRc
11850 28 70 43 73 72 2d 3e 70 44 62 2d 3e 70 45 6e 76  (pCsr->pDb->pEnv
11860 2c 20 34 20 2b 20 38 2c 20 26 72 63 29 3b 0a 20  , 4 + 8, &rc);. 
11870 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
11880 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 6e  *.** Allocate an
11890 64 20 72 65 74 75 72 6e 20 61 20 6e 65 77 20 64  d return a new d
118a0 61 74 61 62 61 73 65 20 63 75 72 73 6f 72 2e 0a  atabase cursor..
118b0 2a 2a 0a 2a 2a 20 54 68 69 73 20 6d 65 74 68 6f  **.** This metho
118c0 64 20 73 68 6f 75 6c 64 20 6f 6e 6c 79 20 62 65  d should only be
118d0 20 63 61 6c 6c 65 64 20 74 6f 20 61 6c 6c 6f 63   called to alloc
118e0 61 74 65 20 75 73 65 72 20 63 75 72 73 6f 72 73  ate user cursors
118f0 2e 20 41 73 20 69 74 20 6d 61 79 0a 2a 2a 20 72  . As it may.** r
11900 65 63 79 63 6c 65 20 61 20 63 75 72 73 6f 72 20  ecycle a cursor 
11910 66 72 6f 6d 20 6c 73 6d 5f 64 62 2e 70 43 73 72  from lsm_db.pCsr
11920 43 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74 20 6c 73  Cache..*/.int ls
11930 6d 4d 43 75 72 73 6f 72 4e 65 77 28 0a 20 20 6c  mMCursorNew(.  l
11940 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20 20 20  sm_db *pDb,     
11950 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
11960 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c  * Database handl
11970 65 20 2a 2f 0a 20 20 4d 75 6c 74 69 43 75 72 73  e */.  MultiCurs
11980 6f 72 20 2a 2a 70 70 43 73 72 20 20 20 20 20 20  or **ppCsr      
11990 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 41         /* OUT: A
119a0 6c 6c 6f 63 61 74 65 64 20 63 75 72 73 6f 72 20  llocated cursor 
119b0 2a 2f 0a 29 7b 0a 20 20 4d 75 6c 74 69 43 75 72  */.){.  MultiCur
119c0 73 6f 72 20 2a 70 43 73 72 20 3d 20 30 3b 0a 20  sor *pCsr = 0;. 
119d0 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
119e0 3b 0a 0a 20 20 69 66 28 20 70 44 62 2d 3e 70 43  ;..  if( pDb->pC
119f0 73 72 43 61 63 68 65 20 29 7b 0a 20 20 20 20 69  srCache ){.    i
11a00 6e 74 20 62 4f 6c 64 3b 20 20 20 20 20 20 20 20  nt bOld;        
11a10 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
11a20 54 72 75 65 20 69 66 20 74 68 65 72 65 20 69 73  True if there is
11a30 20 61 6e 20 6f 6c 64 20 69 6e 2d 6d 65 6d 6f 72   an old in-memor
11a40 79 20 74 72 65 65 20 2a 2f 0a 0a 20 20 20 20 2f  y tree */..    /
11a50 2a 20 52 65 6d 6f 76 65 20 61 20 63 75 72 73 6f  * Remove a curso
11a60 72 20 66 72 6f 6d 20 74 68 65 20 70 43 73 72 43  r from the pCsrC
11a70 61 63 68 65 20 6c 69 73 74 20 61 6e 64 20 61 64  ache list and ad
11a80 64 20 69 74 20 74 6f 20 74 68 65 20 6f 70 65 6e  d it to the open
11a90 20 6c 69 73 74 2e 20 2a 2f 0a 20 20 20 20 70 43   list. */.    pC
11aa0 73 72 20 3d 20 70 44 62 2d 3e 70 43 73 72 43 61  sr = pDb->pCsrCa
11ab0 63 68 65 3b 0a 20 20 20 20 70 44 62 2d 3e 70 43  che;.    pDb->pC
11ac0 73 72 43 61 63 68 65 20 3d 20 70 43 73 72 2d 3e  srCache = pCsr->
11ad0 70 4e 65 78 74 3b 0a 20 20 20 20 70 43 73 72 2d  pNext;.    pCsr-
11ae0 3e 70 4e 65 78 74 20 3d 20 70 44 62 2d 3e 70 43  >pNext = pDb->pC
11af0 73 72 3b 0a 20 20 20 20 70 44 62 2d 3e 70 43 73  sr;.    pDb->pCs
11b00 72 20 3d 20 70 43 73 72 3b 0a 0a 20 20 20 20 2f  r = pCsr;..    /
11b10 2a 20 54 68 65 20 63 75 72 73 6f 72 20 63 61 6e  * The cursor can
11b20 20 61 6c 6d 6f 73 74 20 62 65 20 75 73 65 64 20   almost be used 
11b30 61 73 20 69 73 2c 20 65 78 63 65 70 74 20 74 68  as is, except th
11b40 61 74 20 74 68 65 20 6f 6c 64 20 69 6e 2d 6d 65  at the old in-me
11b50 6d 6f 72 79 0a 20 20 20 20 2a 2a 20 74 72 65 65  mory.    ** tree
11b60 20 63 75 72 73 6f 72 20 6d 61 79 20 62 65 20 70   cursor may be p
11b70 72 65 73 65 6e 74 20 61 6e 64 20 6e 6f 74 20 72  resent and not r
11b80 65 71 75 69 72 65 64 2c 20 6f 72 20 72 65 71 75  equired, or requ
11b90 69 72 65 64 20 61 6e 64 20 6e 6f 74 0a 20 20 20  ired and not.   
11ba0 20 2a 2a 20 70 72 65 73 65 6e 74 2e 20 46 69 78   ** present. Fix
11bb0 20 74 68 69 73 20 69 66 20 72 65 71 75 69 72 65   this if require
11bc0 64 2e 20 20 2a 2f 0a 20 20 20 20 62 4f 6c 64 20  d.  */.    bOld 
11bd0 3d 20 28 6c 73 6d 54 72 65 65 48 61 73 4f 6c 64  = (lsmTreeHasOld
11be0 28 70 44 62 29 20 26 26 20 70 44 62 2d 3e 74 72  (pDb) && pDb->tr
11bf0 65 65 68 64 72 2e 69 4f 6c 64 4c 6f 67 21 3d 70  eehdr.iOldLog!=p
11c00 44 62 2d 3e 70 43 6c 69 65 6e 74 2d 3e 69 4c 6f  Db->pClient->iLo
11c10 67 4f 66 66 29 3b 0a 20 20 20 20 69 66 28 20 21  gOff);.    if( !
11c20 62 4f 6c 64 20 26 26 20 70 43 73 72 2d 3e 61 70  bOld && pCsr->ap
11c30 54 72 65 65 43 73 72 5b 31 5d 20 29 7b 0a 20 20  TreeCsr[1] ){.  
11c40 20 20 20 20 6c 73 6d 54 72 65 65 43 75 72 73 6f      lsmTreeCurso
11c50 72 44 65 73 74 72 6f 79 28 70 43 73 72 2d 3e 61  rDestroy(pCsr->a
11c60 70 54 72 65 65 43 73 72 5b 31 5d 29 3b 0a 20 20  pTreeCsr[1]);.  
11c70 20 20 20 20 70 43 73 72 2d 3e 61 70 54 72 65 65      pCsr->apTree
11c80 43 73 72 5b 31 5d 20 3d 20 30 3b 0a 20 20 20 20  Csr[1] = 0;.    
11c90 7d 65 6c 73 65 20 69 66 28 20 62 4f 6c 64 20 26  }else if( bOld &
11ca0 26 20 21 70 43 73 72 2d 3e 61 70 54 72 65 65 43  & !pCsr->apTreeC
11cb0 73 72 5b 31 5d 20 29 7b 0a 20 20 20 20 20 20 72  sr[1] ){.      r
11cc0 63 20 3d 20 6c 73 6d 54 72 65 65 43 75 72 73 6f  c = lsmTreeCurso
11cd0 72 4e 65 77 28 70 44 62 2c 20 31 2c 20 26 70 43  rNew(pDb, 1, &pC
11ce0 73 72 2d 3e 61 70 54 72 65 65 43 73 72 5b 31 5d  sr->apTreeCsr[1]
11cf0 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 43  );.    }..    pC
11d00 73 72 2d 3e 66 6c 61 67 73 20 3d 20 28 43 55 52  sr->flags = (CUR
11d10 53 4f 52 5f 49 47 4e 4f 52 45 5f 53 59 53 54 45  SOR_IGNORE_SYSTE
11d20 4d 20 7c 20 43 55 52 53 4f 52 5f 49 47 4e 4f 52  M | CURSOR_IGNOR
11d30 45 5f 44 45 4c 45 54 45 29 3b 0a 0a 20 20 7d 65  E_DELETE);..  }e
11d40 6c 73 65 7b 0a 20 20 20 20 70 43 73 72 20 3d 20  lse{.    pCsr = 
11d50 6d 75 6c 74 69 43 75 72 73 6f 72 4e 65 77 28 70  multiCursorNew(p
11d60 44 62 2c 20 26 72 63 29 3b 0a 20 20 20 20 69 66  Db, &rc);.    if
11d70 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 20 72  ( rc==LSM_OK ) r
11d80 63 20 3d 20 6d 75 6c 74 69 43 75 72 73 6f 72 49  c = multiCursorI
11d90 6e 69 74 28 70 43 73 72 2c 20 70 44 62 2d 3e 70  nit(pCsr, pDb->p
11da0 43 6c 69 65 6e 74 29 3b 0a 20 20 7d 0a 0a 20 20  Client);.  }..  
11db0 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29  if( rc!=LSM_OK )
11dc0 7b 0a 20 20 20 20 6c 73 6d 4d 43 75 72 73 6f 72  {.    lsmMCursor
11dd0 43 6c 6f 73 65 28 70 43 73 72 2c 20 30 29 3b 0a  Close(pCsr, 0);.
11de0 20 20 20 20 70 43 73 72 20 3d 20 30 3b 0a 20 20      pCsr = 0;.  
11df0 7d 0a 20 20 61 73 73 65 72 74 28 20 28 72 63 3d  }.  assert( (rc=
11e00 3d 4c 53 4d 5f 4f 4b 29 3d 3d 28 70 43 73 72 21  =LSM_OK)==(pCsr!
11e10 3d 30 29 20 29 3b 0a 20 20 2a 70 70 43 73 72 20  =0) );.  *ppCsr 
11e20 3d 20 70 43 73 72 3b 0a 20 20 72 65 74 75 72 6e  = pCsr;.  return
11e30 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69   rc;.}..static i
11e40 6e 74 20 6d 75 6c 74 69 43 75 72 73 6f 72 47 65  nt multiCursorGe
11e50 74 56 61 6c 28 0a 20 20 4d 75 6c 74 69 43 75 72  tVal(.  MultiCur
11e60 73 6f 72 20 2a 70 43 73 72 2c 20 0a 20 20 69 6e  sor *pCsr, .  in
11e70 74 20 69 56 61 6c 2c 20 0a 20 20 76 6f 69 64 20  t iVal, .  void 
11e80 2a 2a 70 70 56 61 6c 2c 20 0a 20 20 69 6e 74 20  **ppVal, .  int 
11e90 2a 70 6e 56 61 6c 0a 29 7b 0a 20 20 69 6e 74 20  *pnVal.){.  int 
11ea0 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20 20  rc = LSM_OK;..  
11eb0 2a 70 70 56 61 6c 20 3d 20 30 3b 0a 20 20 2a 70  *ppVal = 0;.  *p
11ec0 6e 56 61 6c 20 3d 20 30 3b 0a 0a 20 20 73 77 69  nVal = 0;..  swi
11ed0 74 63 68 28 20 69 56 61 6c 20 29 7b 0a 20 20 20  tch( iVal ){.   
11ee0 20 63 61 73 65 20 43 55 52 53 4f 52 5f 44 41 54   case CURSOR_DAT
11ef0 41 5f 54 52 45 45 30 3a 0a 20 20 20 20 63 61 73  A_TREE0:.    cas
11f00 65 20 43 55 52 53 4f 52 5f 44 41 54 41 5f 54 52  e CURSOR_DATA_TR
11f10 45 45 31 3a 20 7b 0a 20 20 20 20 20 20 54 72 65  EE1: {.      Tre
11f20 65 43 75 72 73 6f 72 20 2a 70 54 72 65 65 43 73  eCursor *pTreeCs
11f30 72 20 3d 20 70 43 73 72 2d 3e 61 70 54 72 65 65  r = pCsr->apTree
11f40 43 73 72 5b 69 56 61 6c 2d 43 55 52 53 4f 52 5f  Csr[iVal-CURSOR_
11f50 44 41 54 41 5f 54 52 45 45 30 5d 3b 0a 20 20 20  DATA_TREE0];.   
11f60 20 20 20 69 66 28 20 6c 73 6d 54 72 65 65 43 75     if( lsmTreeCu
11f70 72 73 6f 72 56 61 6c 69 64 28 70 54 72 65 65 43  rsorValid(pTreeC
11f80 73 72 29 20 29 7b 0a 20 20 20 20 20 20 20 20 6c  sr) ){.        l
11f90 73 6d 54 72 65 65 43 75 72 73 6f 72 56 61 6c 75  smTreeCursorValu
11fa0 65 28 70 54 72 65 65 43 73 72 2c 20 70 70 56 61  e(pTreeCsr, ppVa
11fb0 6c 2c 20 70 6e 56 61 6c 29 3b 0a 20 20 20 20 20  l, pnVal);.     
11fc0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
11fd0 2a 70 70 56 61 6c 20 3d 20 30 3b 0a 20 20 20 20  *ppVal = 0;.    
11fe0 20 20 20 20 2a 70 6e 56 61 6c 20 3d 20 30 3b 0a      *pnVal = 0;.
11ff0 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72        }.      br
12000 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  eak;.    }..    
12010 63 61 73 65 20 43 55 52 53 4f 52 5f 44 41 54 41  case CURSOR_DATA
12020 5f 53 59 53 54 45 4d 3a 20 7b 0a 20 20 20 20 20  _SYSTEM: {.     
12030 20 53 6e 61 70 73 68 6f 74 20 2a 70 57 6f 72 6b   Snapshot *pWork
12040 65 72 20 3d 20 70 43 73 72 2d 3e 70 44 62 2d 3e  er = pCsr->pDb->
12050 70 57 6f 72 6b 65 72 3b 0a 20 20 20 20 20 20 69  pWorker;.      i
12060 66 28 20 70 57 6f 72 6b 65 72 20 0a 20 20 20 20  f( pWorker .    
12070 20 20 20 26 26 20 28 70 43 73 72 2d 3e 69 46 72     && (pCsr->iFr
12080 65 65 20 25 20 32 29 3d 3d 30 0a 20 20 20 20 20  ee % 2)==0.     
12090 20 20 26 26 20 70 43 73 72 2d 3e 69 46 72 65 65    && pCsr->iFree
120a0 20 3c 20 28 70 57 6f 72 6b 65 72 2d 3e 66 72 65   < (pWorker->fre
120b0 65 6c 69 73 74 2e 6e 45 6e 74 72 79 2a 32 29 0a  elist.nEntry*2).
120c0 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20        ){.       
120d0 20 69 6e 74 20 69 45 6e 74 72 79 20 3d 20 70 57   int iEntry = pW
120e0 6f 72 6b 65 72 2d 3e 66 72 65 65 6c 69 73 74 2e  orker->freelist.
120f0 6e 45 6e 74 72 79 20 2d 20 31 20 2d 20 28 70 43  nEntry - 1 - (pC
12100 73 72 2d 3e 69 46 72 65 65 20 2f 20 32 29 3b 0a  sr->iFree / 2);.
12110 20 20 20 20 20 20 20 20 75 38 20 2a 61 56 61 6c          u8 *aVal
12120 20 3d 20 26 28 28 75 38 20 2a 29 28 70 43 73 72   = &((u8 *)(pCsr
12130 2d 3e 70 53 79 73 74 65 6d 56 61 6c 29 29 5b 34  ->pSystemVal))[4
12140 5d 3b 0a 20 20 20 20 20 20 20 20 6c 73 6d 50 75  ];.        lsmPu
12150 74 55 36 34 28 61 56 61 6c 2c 20 70 57 6f 72 6b  tU64(aVal, pWork
12160 65 72 2d 3e 66 72 65 65 6c 69 73 74 2e 61 45 6e  er->freelist.aEn
12170 74 72 79 5b 69 45 6e 74 72 79 5d 2e 69 49 64 29  try[iEntry].iId)
12180 3b 0a 20 20 20 20 20 20 20 20 2a 70 70 56 61 6c  ;.        *ppVal
12190 20 3d 20 61 56 61 6c 3b 0a 20 20 20 20 20 20 20   = aVal;.       
121a0 20 2a 70 6e 56 61 6c 20 3d 20 38 3b 0a 20 20 20   *pnVal = 8;.   
121b0 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b     }.      break
121c0 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 64 65 66  ;.    }..    def
121d0 61 75 6c 74 3a 20 7b 0a 20 20 20 20 20 20 69 6e  ault: {.      in
121e0 74 20 69 50 74 72 20 3d 20 69 56 61 6c 2d 43 55  t iPtr = iVal-CU
121f0 52 53 4f 52 5f 44 41 54 41 5f 53 45 47 4d 45 4e  RSOR_DATA_SEGMEN
12200 54 3b 0a 20 20 20 20 20 20 69 66 28 20 69 50 74  T;.      if( iPt
12210 72 3c 70 43 73 72 2d 3e 6e 50 74 72 20 29 7b 0a  r<pCsr->nPtr ){.
12220 20 20 20 20 20 20 20 20 53 65 67 6d 65 6e 74 50          SegmentP
12230 74 72 20 2a 70 50 74 72 20 3d 20 26 70 43 73 72  tr *pPtr = &pCsr
12240 2d 3e 61 50 74 72 5b 69 50 74 72 5d 3b 0a 20 20  ->aPtr[iPtr];.  
12250 20 20 20 20 20 20 69 66 28 20 70 50 74 72 2d 3e        if( pPtr->
12260 70 50 67 20 29 7b 0a 20 20 20 20 20 20 20 20 20  pPg ){.         
12270 20 2a 70 70 56 61 6c 20 3d 20 70 50 74 72 2d 3e   *ppVal = pPtr->
12280 70 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 20 20  pVal;.          
12290 2a 70 6e 56 61 6c 20 3d 20 70 50 74 72 2d 3e 6e  *pnVal = pPtr->n
122a0 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  Val;.        }. 
122b0 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
122c0 0a 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d  ..  assert( rc==
122d0 4c 53 4d 5f 4f 4b 20 7c 7c 20 28 2a 70 70 56 61  LSM_OK || (*ppVa
122e0 6c 3d 3d 30 20 26 26 20 2a 70 6e 56 61 6c 3d 3d  l==0 && *pnVal==
122f0 30 29 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  0) );.  return r
12300 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
12310 20 6d 75 6c 74 69 43 75 72 73 6f 72 41 64 76 61   multiCursorAdva
12320 6e 63 65 28 4d 75 6c 74 69 43 75 72 73 6f 72 20  nce(MultiCursor 
12330 2a 70 43 73 72 2c 20 69 6e 74 20 62 52 65 76 65  *pCsr, int bReve
12340 72 73 65 29 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  rse);../*.** Thi
12350 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
12360 6c 6c 65 64 20 62 79 20 77 6f 72 6b 65 72 20 63  lled by worker c
12370 6f 6e 6e 65 63 74 69 6f 6e 73 20 74 6f 20 77 61  onnections to wa
12380 6c 6b 20 74 68 65 20 70 61 72 74 20 6f 66 20 74  lk the part of t
12390 68 65 0a 2a 2a 20 66 72 65 65 2d 6c 69 73 74 20  he.** free-list 
123a0 73 74 6f 72 65 64 20 77 69 74 68 69 6e 20 74 68  stored within th
123b0 65 20 4c 53 4d 20 64 61 74 61 20 73 74 72 75 63  e LSM data struc
123c0 74 75 72 65 2e 0a 2a 2f 0a 69 6e 74 20 6c 73 6d  ture..*/.int lsm
123d0 53 6f 72 74 65 64 57 61 6c 6b 46 72 65 65 6c 69  SortedWalkFreeli
123e0 73 74 28 0a 20 20 6c 73 6d 5f 64 62 20 2a 70 44  st(.  lsm_db *pD
123f0 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
12400 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
12410 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e  e handle */.  in
12420 74 20 62 52 65 76 65 72 73 65 2c 20 20 20 20 20  t bReverse,     
12430 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
12440 20 54 72 75 65 20 74 6f 20 69 74 65 72 61 74 65   True to iterate
12450 20 66 72 6f 6d 20 6c 61 72 67 65 73 74 20 74 6f   from largest to
12460 20 73 6d 61 6c 6c 65 73 74 20 2a 2f 0a 20 20 69   smallest */.  i
12470 6e 74 20 28 2a 78 29 28 76 6f 69 64 20 2a 2c 20  nt (*x)(void *, 
12480 69 6e 74 2c 20 69 36 34 29 2c 20 20 20 20 20 2f  int, i64),     /
12490 2a 20 43 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74  * Callback funct
124a0 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  ion */.  void *p
124b0 43 74 78 20 20 20 20 20 20 20 20 20 20 20 20 20  Ctx             
124c0 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73           /* Firs
124d0 74 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 70 61  t argument to pa
124e0 73 73 20 74 6f 20 63 61 6c 6c 62 61 63 6b 20 2a  ss to callback *
124f0 2f 0a 29 7b 0a 20 20 4d 75 6c 74 69 43 75 72 73  /.){.  MultiCurs
12500 6f 72 20 2a 70 43 73 72 3b 20 20 20 20 20 20 20  or *pCsr;       
12510 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73 6f 72         /* Cursor
12520 20 75 73 65 64 20 74 6f 20 72 65 61 64 20 64 62   used to read db
12530 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c   */.  int rc = L
12540 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  SM_OK;          
12550 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
12560 43 6f 64 65 20 2a 2f 0a 20 20 53 6e 61 70 73 68  Code */.  Snapsh
12570 6f 74 20 2a 70 53 6e 61 70 20 3d 20 30 3b 0a 0a  ot *pSnap = 0;..
12580 20 20 61 73 73 65 72 74 28 20 70 44 62 2d 3e 70    assert( pDb->p
12590 57 6f 72 6b 65 72 20 29 3b 0a 20 20 69 66 28 20  Worker );.  if( 
125a0 70 44 62 2d 3e 62 49 6e 63 72 4d 65 72 67 65 20  pDb->bIncrMerge 
125b0 29 7b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 43  ){.    rc = lsmC
125c0 68 65 63 6b 70 6f 69 6e 74 44 65 73 65 72 69 61  heckpointDeseria
125d0 6c 69 7a 65 28 70 44 62 2c 20 30 2c 20 70 44 62  lize(pDb, 0, pDb
125e0 2d 3e 70 53 68 6d 68 64 72 2d 3e 61 53 6e 61 70  ->pShmhdr->aSnap
125f0 31 2c 20 26 70 53 6e 61 70 29 3b 0a 20 20 20 20  1, &pSnap);.    
12600 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29  if( rc!=LSM_OK )
12610 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 65   return rc;.  }e
12620 6c 73 65 7b 0a 20 20 20 20 70 53 6e 61 70 20 3d  lse{.    pSnap =
12630 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 3b 0a 20   pDb->pWorker;. 
12640 20 7d 0a 0a 20 20 70 43 73 72 20 3d 20 6d 75 6c   }..  pCsr = mul
12650 74 69 43 75 72 73 6f 72 4e 65 77 28 70 44 62 2c  tiCursorNew(pDb,
12660 20 26 72 63 29 3b 0a 20 20 69 66 28 20 70 43 73   &rc);.  if( pCs
12670 72 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 6d 75  r ){.    rc = mu
12680 6c 74 69 43 75 72 73 6f 72 41 64 64 41 6c 6c 28  ltiCursorAddAll(
12690 70 43 73 72 2c 20 70 53 6e 61 70 29 3b 0a 20 20  pCsr, pSnap);.  
126a0 20 20 70 43 73 72 2d 3e 66 6c 61 67 73 20 7c 3d    pCsr->flags |=
126b0 20 43 55 52 53 4f 52 5f 49 47 4e 4f 52 45 5f 44   CURSOR_IGNORE_D
126c0 45 4c 45 54 45 3b 0a 20 20 7d 0a 20 20 0a 20 20  ELETE;.  }.  .  
126d0 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
126e0 7b 0a 20 20 20 20 69 66 28 20 62 52 65 76 65 72  {.    if( bRever
126f0 73 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72  se==0 ){.      r
12700 63 20 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 4c 61  c = lsmMCursorLa
12710 73 74 28 70 43 73 72 29 3b 0a 20 20 20 20 7d 65  st(pCsr);.    }e
12720 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  lse{.      rc = 
12730 6c 73 6d 4d 43 75 72 73 6f 72 53 65 65 6b 28 70  lsmMCursorSeek(p
12740 43 73 72 2c 20 31 2c 20 22 22 2c 20 30 2c 20 4c  Csr, 1, "", 0, L
12750 53 4d 5f 53 45 45 4b 5f 47 45 29 3b 0a 20 20 20  SM_SEEK_GE);.   
12760 20 7d 0a 0a 20 20 20 20 77 68 69 6c 65 28 20 72   }..    while( r
12770 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 6c 73 6d  c==LSM_OK && lsm
12780 4d 43 75 72 73 6f 72 56 61 6c 69 64 28 70 43 73  MCursorValid(pCs
12790 72 29 20 26 26 20 72 74 49 73 53 79 73 74 65 6d  r) && rtIsSystem
127a0 28 70 43 73 72 2d 3e 65 54 79 70 65 29 20 29 7b  (pCsr->eType) ){
127b0 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70 4b 65  .      void *pKe
127c0 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 0a 20 20 20  y; int nKey;.   
127d0 20 20 20 76 6f 69 64 20 2a 70 56 61 6c 20 3d 20     void *pVal = 
127e0 30 3b 20 69 6e 74 20 6e 56 61 6c 20 3d 20 30 3b  0; int nVal = 0;
127f0 0a 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d  ..      rc = lsm
12800 4d 43 75 72 73 6f 72 4b 65 79 28 70 43 73 72 2c  MCursorKey(pCsr,
12810 20 26 70 4b 65 79 2c 20 26 6e 4b 65 79 29 3b 0a   &pKey, &nKey);.
12820 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53        if( rc==LS
12830 4d 5f 4f 4b 20 29 20 72 63 20 3d 20 6c 73 6d 4d  M_OK ) rc = lsmM
12840 43 75 72 73 6f 72 56 61 6c 75 65 28 70 43 73 72  CursorValue(pCsr
12850 2c 20 26 70 56 61 6c 2c 20 26 6e 56 61 6c 29 3b  , &pVal, &nVal);
12860 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  .      if( rc==L
12870 53 4d 5f 4f 4b 20 26 26 20 28 6e 4b 65 79 21 3d  SM_OK && (nKey!=
12880 34 20 7c 7c 20 6e 56 61 6c 21 3d 38 29 20 29 20  4 || nVal!=8) ) 
12890 72 63 20 3d 20 4c 53 4d 5f 43 4f 52 52 55 50 54  rc = LSM_CORRUPT
128a0 5f 42 4b 50 54 3b 0a 0a 20 20 20 20 20 20 69 66  _BKPT;..      if
128b0 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a  ( rc==LSM_OK ){.
128c0 20 20 20 20 20 20 20 20 69 6e 74 20 69 42 6c 6b          int iBlk
128d0 3b 0a 20 20 20 20 20 20 20 20 69 36 34 20 69 53  ;.        i64 iS
128e0 6e 61 70 3b 0a 20 20 20 20 20 20 20 20 69 42 6c  nap;.        iBl
128f0 6b 20 3d 20 28 69 6e 74 29 28 7e 28 6c 73 6d 47  k = (int)(~(lsmG
12900 65 74 55 33 32 28 28 75 38 20 2a 29 70 4b 65 79  etU32((u8 *)pKey
12910 29 29 29 3b 0a 20 20 20 20 20 20 20 20 69 53 6e  )));.        iSn
12920 61 70 20 3d 20 28 69 36 34 29 6c 73 6d 47 65 74  ap = (i64)lsmGet
12930 55 36 34 28 28 75 38 20 2a 29 70 56 61 6c 29 3b  U64((u8 *)pVal);
12940 0a 20 20 20 20 20 20 20 20 69 66 28 20 78 28 70  .        if( x(p
12950 43 74 78 2c 20 69 42 6c 6b 2c 20 69 53 6e 61 70  Ctx, iBlk, iSnap
12960 29 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  ) ) break;.     
12970 20 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75 72     rc = multiCur
12980 73 6f 72 41 64 76 61 6e 63 65 28 70 43 73 72 2c  sorAdvance(pCsr,
12990 20 21 62 52 65 76 65 72 73 65 29 3b 0a 20 20 20   !bReverse);.   
129a0 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
129b0 20 20 6c 73 6d 4d 43 75 72 73 6f 72 43 6c 6f 73    lsmMCursorClos
129c0 65 28 70 43 73 72 2c 20 30 29 3b 0a 20 20 69 66  e(pCsr, 0);.  if
129d0 28 20 70 53 6e 61 70 21 3d 70 44 62 2d 3e 70 57  ( pSnap!=pDb->pW
129e0 6f 72 6b 65 72 20 29 7b 0a 20 20 20 20 6c 73 6d  orker ){.    lsm
129f0 46 72 65 65 53 6e 61 70 73 68 6f 74 28 70 44 62  FreeSnapshot(pDb
12a00 2d 3e 70 45 6e 76 2c 20 70 53 6e 61 70 29 3b 0a  ->pEnv, pSnap);.
12a10 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
12a20 3b 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 53 6f 72 74  ;.}..int lsmSort
12a30 65 64 4c 6f 61 64 46 72 65 65 6c 69 73 74 28 0a  edLoadFreelist(.
12a40 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20    lsm_db *pDb,  
12a50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12a60 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61    /* Database ha
12a70 6e 64 6c 65 20 28 6d 75 73 74 20 62 65 20 77 6f  ndle (must be wo
12a80 72 6b 65 72 29 20 2a 2f 0a 20 20 76 6f 69 64 20  rker) */.  void 
12a90 2a 2a 70 70 56 61 6c 2c 20 20 20 20 20 20 20 20  **ppVal,        
12aa0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
12ab0 54 3a 20 42 6c 6f 62 20 63 6f 6e 74 61 69 6e 69  T: Blob containi
12ac0 6e 67 20 4c 53 4d 20 66 72 65 65 2d 6c 69 73 74  ng LSM free-list
12ad0 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 56 61 6c   */.  int *pnVal
12ae0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12af0 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 69        /* OUT: Si
12b00 7a 65 20 6f 66 20 2a 70 70 56 61 6c 20 62 6c 6f  ze of *ppVal blo
12b10 62 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 29 7b  b in bytes */.){
12b20 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a  .  MultiCursor *
12b30 70 43 73 72 3b 20 20 20 20 20 20 20 20 20 20 20  pCsr;           
12b40 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 75 73 65     /* Cursor use
12b50 64 20 74 6f 20 72 65 74 72 65 69 76 65 20 66 72  d to retreive fr
12b60 65 65 2d 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74  ee-list */.  int
12b70 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20   rc = LSM_OK;   
12b80 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12b90 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 0a  Return Code */..
12ba0 20 20 61 73 73 65 72 74 28 20 70 44 62 2d 3e 70    assert( pDb->p
12bb0 57 6f 72 6b 65 72 20 29 3b 0a 20 20 61 73 73 65  Worker );.  asse
12bc0 72 74 28 20 2a 70 70 56 61 6c 3d 3d 30 20 26 26  rt( *ppVal==0 &&
12bd0 20 2a 70 6e 56 61 6c 3d 3d 30 20 29 3b 0a 0a 20   *pnVal==0 );.. 
12be0 20 70 43 73 72 20 3d 20 6d 75 6c 74 69 43 75 72   pCsr = multiCur
12bf0 73 6f 72 4e 65 77 28 70 44 62 2c 20 26 72 63 29  sorNew(pDb, &rc)
12c00 3b 0a 20 20 69 66 28 20 70 43 73 72 20 29 7b 0a  ;.  if( pCsr ){.
12c10 20 20 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75      rc = multiCu
12c20 72 73 6f 72 41 64 64 41 6c 6c 28 70 43 73 72 2c  rsorAddAll(pCsr,
12c30 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 29 3b 0a   pDb->pWorker);.
12c40 20 20 20 20 70 43 73 72 2d 3e 66 6c 61 67 73 20      pCsr->flags 
12c50 7c 3d 20 43 55 52 53 4f 52 5f 49 47 4e 4f 52 45  |= CURSOR_IGNORE
12c60 5f 44 45 4c 45 54 45 3b 0a 20 20 7d 0a 20 20 0a  _DELETE;.  }.  .
12c70 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
12c80 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d   ){.    rc = lsm
12c90 4d 43 75 72 73 6f 72 4c 61 73 74 28 70 43 73 72  MCursorLast(pCsr
12ca0 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  );.    if( rc==L
12cb0 53 4d 5f 4f 4b 20 0a 20 20 20 20 20 26 26 20 72  SM_OK .     && r
12cc0 74 49 73 57 72 69 74 65 28 70 43 73 72 2d 3e 65  tIsWrite(pCsr->e
12cd0 54 79 70 65 29 20 26 26 20 72 74 49 73 53 79 73  Type) && rtIsSys
12ce0 74 65 6d 28 70 43 73 72 2d 3e 65 54 79 70 65 29  tem(pCsr->eType)
12cf0 0a 20 20 20 20 20 26 26 20 70 43 73 72 2d 3e 6b  .     && pCsr->k
12d00 65 79 2e 6e 44 61 74 61 3d 3d 38 20 0a 20 20 20  ey.nData==8 .   
12d10 20 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 70    && 0==memcmp(p
12d20 43 73 72 2d 3e 6b 65 79 2e 70 44 61 74 61 2c 20  Csr->key.pData, 
12d30 22 46 52 45 45 4c 49 53 54 22 2c 20 38 29 0a 20  "FREELIST", 8). 
12d40 20 20 20 29 7b 0a 20 20 20 20 20 20 76 6f 69 64     ){.      void
12d50 20 2a 70 56 61 6c 3b 20 69 6e 74 20 6e 56 61 6c   *pVal; int nVal
12d60 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c  ;         /* Val
12d70 75 65 20 72 65 61 64 20 66 72 6f 6d 20 64 61 74  ue read from dat
12d80 61 62 61 73 65 20 2a 2f 0a 20 20 20 20 20 20 72  abase */.      r
12d90 63 20 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 56 61  c = lsmMCursorVa
12da0 6c 75 65 28 70 43 73 72 2c 20 26 70 56 61 6c 2c  lue(pCsr, &pVal,
12db0 20 26 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 69   &nVal);.      i
12dc0 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b  f( rc==LSM_OK ){
12dd0 0a 20 20 20 20 20 20 20 20 2a 70 70 56 61 6c 20  .        *ppVal 
12de0 3d 20 6c 73 6d 4d 61 6c 6c 6f 63 52 63 28 70 44  = lsmMallocRc(pD
12df0 62 2d 3e 70 45 6e 76 2c 20 6e 56 61 6c 2c 20 26  b->pEnv, nVal, &
12e00 72 63 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  rc);.        if(
12e10 20 2a 70 70 56 61 6c 20 29 7b 0a 20 20 20 20 20   *ppVal ){.     
12e20 20 20 20 20 20 6d 65 6d 63 70 79 28 2a 70 70 56       memcpy(*ppV
12e30 61 6c 2c 20 70 56 61 6c 2c 20 6e 56 61 6c 29 3b  al, pVal, nVal);
12e40 0a 20 20 20 20 20 20 20 20 20 20 2a 70 6e 56 61  .          *pnVa
12e50 6c 20 3d 20 6e 56 61 6c 3b 0a 20 20 20 20 20 20  l = nVal;.      
12e60 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
12e70 7d 0a 0a 20 20 20 20 6c 73 6d 4d 43 75 72 73 6f  }..    lsmMCurso
12e80 72 43 6c 6f 73 65 28 70 43 73 72 2c 20 30 29 3b  rClose(pCsr, 0);
12e90 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
12ea0 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
12eb0 20 6d 75 6c 74 69 43 75 72 73 6f 72 41 6c 6c 6f   multiCursorAllo
12ec0 63 54 72 65 65 28 4d 75 6c 74 69 43 75 72 73 6f  cTree(MultiCurso
12ed0 72 20 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74 20  r *pCsr){.  int 
12ee0 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 69  rc = LSM_OK;.  i
12ef0 66 28 20 70 43 73 72 2d 3e 61 54 72 65 65 3d 3d  f( pCsr->aTree==
12f00 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79  0 ){.    int nBy
12f10 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  te;             
12f20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
12f30 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f  of space to allo
12f40 63 61 74 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20  cate */.    int 
12f50 6e 4d 69 6e 3b 20 20 20 20 20 20 20 20 20 20 20  nMin;           
12f60 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 74            /* Tot
12f70 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 63 75 72  al number of cur
12f80 73 6f 72 73 20 62 65 69 6e 67 20 6d 65 72 67 65  sors being merge
12f90 64 20 2a 2f 0a 0a 20 20 20 20 6e 4d 69 6e 20 3d  d */..    nMin =
12fa0 20 43 55 52 53 4f 52 5f 44 41 54 41 5f 53 45 47   CURSOR_DATA_SEG
12fb0 4d 45 4e 54 20 2b 20 70 43 73 72 2d 3e 6e 50 74  MENT + pCsr->nPt
12fc0 72 20 2b 20 28 70 43 73 72 2d 3e 70 42 74 43 73  r + (pCsr->pBtCs
12fd0 72 21 3d 30 29 3b 0a 20 20 20 20 70 43 73 72 2d  r!=0);.    pCsr-
12fe0 3e 6e 54 72 65 65 20 3d 20 32 3b 0a 20 20 20 20  >nTree = 2;.    
12ff0 77 68 69 6c 65 28 20 70 43 73 72 2d 3e 6e 54 72  while( pCsr->nTr
13000 65 65 3c 6e 4d 69 6e 20 29 7b 0a 20 20 20 20 20  ee<nMin ){.     
13010 20 70 43 73 72 2d 3e 6e 54 72 65 65 20 3d 20 70   pCsr->nTree = p
13020 43 73 72 2d 3e 6e 54 72 65 65 2a 32 3b 0a 20 20  Csr->nTree*2;.  
13030 20 20 7d 0a 0a 20 20 20 20 6e 42 79 74 65 20 3d    }..    nByte =
13040 20 73 69 7a 65 6f 66 28 69 6e 74 29 2a 70 43 73   sizeof(int)*pCs
13050 72 2d 3e 6e 54 72 65 65 2a 32 3b 0a 20 20 20 20  r->nTree*2;.    
13060 70 43 73 72 2d 3e 61 54 72 65 65 20 3d 20 28 69  pCsr->aTree = (i
13070 6e 74 20 2a 29 6c 73 6d 4d 61 6c 6c 6f 63 5a 65  nt *)lsmMallocZe
13080 72 6f 52 63 28 70 43 73 72 2d 3e 70 44 62 2d 3e  roRc(pCsr->pDb->
13090 70 45 6e 76 2c 20 6e 42 79 74 65 2c 20 26 72 63  pEnv, nByte, &rc
130a0 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
130b0 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  rc;.}..static vo
130c0 69 64 20 6d 75 6c 74 69 43 75 72 73 6f 72 43 61  id multiCursorCa
130d0 63 68 65 4b 65 79 28 4d 75 6c 74 69 43 75 72 73  cheKey(MultiCurs
130e0 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74 20 2a 70  or *pCsr, int *p
130f0 52 63 29 7b 0a 20 20 69 66 28 20 2a 70 52 63 3d  Rc){.  if( *pRc=
13100 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 76  =LSM_OK ){.    v
13110 6f 69 64 20 2a 70 4b 65 79 3b 0a 20 20 20 20 69  oid *pKey;.    i
13120 6e 74 20 6e 4b 65 79 3b 0a 20 20 20 20 6d 75 6c  nt nKey;.    mul
13130 74 69 43 75 72 73 6f 72 47 65 74 4b 65 79 28 70  tiCursorGetKey(p
13140 43 73 72 2c 20 70 43 73 72 2d 3e 61 54 72 65 65  Csr, pCsr->aTree
13150 5b 31 5d 2c 20 26 70 43 73 72 2d 3e 65 54 79 70  [1], &pCsr->eTyp
13160 65 2c 20 26 70 4b 65 79 2c 20 26 6e 4b 65 79 29  e, &pKey, &nKey)
13170 3b 0a 20 20 20 20 2a 70 52 63 20 3d 20 73 6f 72  ;.    *pRc = sor
13180 74 65 64 42 6c 6f 62 53 65 74 28 70 43 73 72 2d  tedBlobSet(pCsr-
13190 3e 70 44 62 2d 3e 70 45 6e 76 2c 20 26 70 43 73  >pDb->pEnv, &pCs
131a0 72 2d 3e 6b 65 79 2c 20 70 4b 65 79 2c 20 6e 4b  r->key, pKey, nK
131b0 65 79 29 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64  ey);.  }.}..#ifd
131c0 65 66 20 4c 53 4d 5f 44 45 42 55 47 5f 45 58 50  ef LSM_DEBUG_EXP
131d0 45 4e 53 49 56 45 0a 73 74 61 74 69 63 20 76 6f  ENSIVE.static vo
131e0 69 64 20 61 73 73 65 72 74 43 75 72 73 6f 72 54  id assertCursorT
131f0 72 65 65 28 4d 75 6c 74 69 43 75 72 73 6f 72 20  ree(MultiCursor 
13200 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74 20 62 52  *pCsr){.  int bR
13210 65 76 20 3d 20 21 21 28 70 43 73 72 2d 3e 66 6c  ev = !!(pCsr->fl
13220 61 67 73 20 26 20 43 55 52 53 4f 52 5f 50 52 45  ags & CURSOR_PRE
13230 56 5f 4f 4b 29 3b 0a 20 20 69 6e 74 20 2a 61 53  V_OK);.  int *aS
13240 61 76 65 20 3d 20 70 43 73 72 2d 3e 61 54 72 65  ave = pCsr->aTre
13250 65 3b 0a 20 20 69 6e 74 20 6e 53 61 76 65 20 3d  e;.  int nSave =
13260 20 70 43 73 72 2d 3e 6e 54 72 65 65 3b 0a 20 20   pCsr->nTree;.  
13270 69 6e 74 20 72 63 3b 0a 0a 20 20 70 43 73 72 2d  int rc;..  pCsr-
13280 3e 61 54 72 65 65 20 3d 20 30 3b 0a 20 20 70 43  >aTree = 0;.  pC
13290 73 72 2d 3e 6e 54 72 65 65 20 3d 20 30 3b 0a 20  sr->nTree = 0;. 
132a0 20 72 63 20 3d 20 6d 75 6c 74 69 43 75 72 73 6f   rc = multiCurso
132b0 72 41 6c 6c 6f 63 54 72 65 65 28 70 43 73 72 29  rAllocTree(pCsr)
132c0 3b 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f  ;.  if( rc==LSM_
132d0 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b  OK ){.    int i;
132e0 0a 20 20 20 20 66 6f 72 28 69 3d 70 43 73 72 2d  .    for(i=pCsr-
132f0 3e 6e 54 72 65 65 2d 31 3b 20 69 3e 30 3b 20 69  >nTree-1; i>0; i
13300 2d 2d 29 7b 0a 20 20 20 20 20 20 6d 75 6c 74 69  --){.      multi
13310 43 75 72 73 6f 72 44 6f 43 6f 6d 70 61 72 65 28  CursorDoCompare(
13320 70 43 73 72 2c 20 69 2c 20 62 52 65 76 29 3b 0a  pCsr, i, bRev);.
13330 20 20 20 20 7d 0a 0a 20 20 20 20 61 73 73 65 72      }..    asser
13340 74 28 20 6e 53 61 76 65 3d 3d 70 43 73 72 2d 3e  t( nSave==pCsr->
13350 6e 54 72 65 65 20 0a 20 20 20 20 20 20 20 20 26  nTree .        &
13360 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 61 53 61 76  & 0==memcmp(aSav
13370 65 2c 20 70 43 73 72 2d 3e 61 54 72 65 65 2c 20  e, pCsr->aTree, 
13380 73 69 7a 65 6f 66 28 69 6e 74 29 2a 6e 53 61 76  sizeof(int)*nSav
13390 65 29 0a 20 20 20 20 29 3b 0a 0a 20 20 20 20 6c  e).    );..    l
133a0 73 6d 46 72 65 65 28 70 43 73 72 2d 3e 70 44 62  smFree(pCsr->pDb
133b0 2d 3e 70 45 6e 76 2c 20 70 43 73 72 2d 3e 61 54  ->pEnv, pCsr->aT
133c0 72 65 65 29 3b 0a 20 20 7d 0a 0a 20 20 70 43 73  ree);.  }..  pCs
133d0 72 2d 3e 61 54 72 65 65 20 3d 20 61 53 61 76 65  r->aTree = aSave
133e0 3b 0a 20 20 70 43 73 72 2d 3e 6e 54 72 65 65 20  ;.  pCsr->nTree 
133f0 3d 20 6e 53 61 76 65 3b 0a 7d 0a 23 65 6c 73 65  = nSave;.}.#else
13400 0a 23 20 64 65 66 69 6e 65 20 61 73 73 65 72 74  .# define assert
13410 43 75 72 73 6f 72 54 72 65 65 28 78 29 0a 23 65  CursorTree(x).#e
13420 6e 64 69 66 0a 0a 73 74 61 74 69 63 20 69 6e 74  ndif..static int
13430 20 6d 63 75 72 73 6f 72 4c 6f 63 61 74 69 6f 6e   mcursorLocation
13440 4f 6b 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a  Ok(MultiCursor *
13450 70 43 73 72 2c 20 69 6e 74 20 62 44 65 6c 65 74  pCsr, int bDelet
13460 65 4f 6b 29 7b 0a 20 20 69 6e 74 20 65 54 79 70  eOk){.  int eTyp
13470 65 20 3d 20 70 43 73 72 2d 3e 65 54 79 70 65 3b  e = pCsr->eType;
13480 0a 20 20 69 6e 74 20 69 4b 65 79 3b 0a 20 20 69  .  int iKey;.  i
13490 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72 64 6d 61  nt i;.  int rdma
134a0 73 6b 3b 0a 20 20 0a 20 20 61 73 73 65 72 74 28  sk;.  .  assert(
134b0 20 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20 28   pCsr->flags & (
134c0 43 55 52 53 4f 52 5f 4e 45 58 54 5f 4f 4b 7c 43  CURSOR_NEXT_OK|C
134d0 55 52 53 4f 52 5f 50 52 45 56 5f 4f 4b 29 20 29  URSOR_PREV_OK) )
134e0 3b 0a 20 20 61 73 73 65 72 74 43 75 72 73 6f 72  ;.  assertCursor
134f0 54 72 65 65 28 70 43 73 72 29 3b 0a 0a 20 20 72  Tree(pCsr);..  r
13500 64 6d 61 73 6b 20 3d 20 28 70 43 73 72 2d 3e 66  dmask = (pCsr->f
13510 6c 61 67 73 20 26 20 43 55 52 53 4f 52 5f 4e 45  lags & CURSOR_NE
13520 58 54 5f 4f 4b 29 20 3f 20 4c 53 4d 5f 45 4e 44  XT_OK) ? LSM_END
13530 5f 44 45 4c 45 54 45 20 3a 20 4c 53 4d 5f 53 54  _DELETE : LSM_ST
13540 41 52 54 5f 44 45 4c 45 54 45 3b 0a 0a 20 20 2f  ART_DELETE;..  /
13550 2a 20 49 66 20 74 68 65 20 63 75 72 73 6f 72 20  * If the cursor 
13560 64 6f 65 73 20 6e 6f 74 20 63 75 72 72 65 6e 74  does not current
13570 6c 79 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20 61  ly point to an a
13580 63 74 75 61 6c 20 64 61 74 61 62 61 73 65 20 6b  ctual database k
13590 65 79 20 28 69 2e 65 2e 0a 20 20 2a 2a 20 69 74  ey (i.e..  ** it
135a0 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 64 65 6c   points to a del
135b0 65 74 65 20 6b 65 79 2c 20 6f 72 20 74 68 65 20  ete key, or the 
135c0 73 74 61 72 74 20 6f 72 20 65 6e 64 20 6f 66 20  start or end of 
135d0 61 20 72 61 6e 67 65 2d 64 65 6c 65 74 65 29 2c  a range-delete),
135e0 20 61 6e 64 0a 20 20 2a 2a 20 74 68 65 20 43 55   and.  ** the CU
135f0 52 53 4f 52 5f 49 47 4e 4f 52 45 5f 44 45 4c 45  RSOR_IGNORE_DELE
13600 54 45 20 66 6c 61 67 20 69 73 20 73 65 74 2c 20  TE flag is set, 
13610 73 6b 69 70 20 70 61 73 74 20 74 68 69 73 20 65  skip past this e
13620 6e 74 72 79 2e 20 20 2a 2f 0a 20 20 69 66 28 20  ntry.  */.  if( 
13630 28 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20 43  (pCsr->flags & C
13640 55 52 53 4f 52 5f 49 47 4e 4f 52 45 5f 44 45 4c  URSOR_IGNORE_DEL
13650 45 54 45 29 20 26 26 20 62 44 65 6c 65 74 65 4f  ETE) && bDeleteO
13660 6b 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20  k==0 ){.    if( 
13670 28 65 54 79 70 65 20 26 20 4c 53 4d 5f 49 4e 53  (eType & LSM_INS
13680 45 52 54 29 3d 3d 30 20 29 20 72 65 74 75 72 6e  ERT)==0 ) return
13690 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66   0;.  }..  /* If
136a0 20 74 68 65 20 63 75 72 73 6f 72 20 70 6f 69 6e   the cursor poin
136b0 74 73 20 74 6f 20 61 20 73 79 73 74 65 6d 20 6b  ts to a system k
136c0 65 79 20 28 66 72 65 65 2d 6c 69 73 74 20 65 6e  ey (free-list en
136d0 74 72 79 29 2c 20 61 6e 64 20 74 68 65 0a 20 20  try), and the.  
136e0 2a 2a 20 43 55 52 53 4f 52 5f 49 47 4e 4f 52 45  ** CURSOR_IGNORE
136f0 5f 53 59 53 54 45 4d 20 66 6c 61 67 20 69 73 20  _SYSTEM flag is 
13700 73 65 74 2c 20 73 6b 69 70 20 74 68 69 65 20 65  set, skip thie e
13710 6e 74 72 79 2e 20 20 2a 2f 0a 20 20 69 66 28 20  ntry.  */.  if( 
13720 28 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20 43  (pCsr->flags & C
13730 55 52 53 4f 52 5f 49 47 4e 4f 52 45 5f 53 59 53  URSOR_IGNORE_SYS
13740 54 45 4d 29 20 26 26 20 72 74 54 6f 70 69 63 28  TEM) && rtTopic(
13750 65 54 79 70 65 29 21 3d 30 20 29 7b 0a 20 20 20  eType)!=0 ){.   
13760 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a   return 0;.  }..
13770 23 69 66 6e 64 65 66 20 4e 44 45 42 55 47 0a 20  #ifndef NDEBUG. 
13780 20 2f 2a 20 54 68 69 73 20 62 6c 6f 63 6b 20 66   /* This block f
13790 69 72 65 73 20 61 73 73 65 72 74 28 29 20 73 74  ires assert() st
137a0 61 74 65 6d 65 6e 74 73 20 74 6f 20 63 68 65 63  atements to chec
137b0 6b 20 6f 6e 65 20 6f 66 20 74 68 65 20 61 73 73  k one of the ass
137c0 75 6d 70 74 69 6f 6e 73 0a 20 20 2a 2a 20 69 6e  umptions.  ** in
137d0 20 74 68 65 20 63 6f 6d 6d 65 6e 74 20 62 65 6c   the comment bel
137e0 6f 77 20 2d 20 74 68 61 74 20 69 66 20 74 68 65  ow - that if the
137f0 20 6c 68 73 20 73 75 62 2d 63 75 72 73 6f 72 20   lhs sub-cursor 
13800 6f 66 20 61 20 6c 65 76 65 6c 20 75 6e 64 65 72  of a level under
13810 67 6f 69 6e 67 0a 20 20 2a 2a 20 61 20 6d 65 72  going.  ** a mer
13820 67 65 20 69 73 20 76 61 6c 69 64 2c 20 74 68 65  ge is valid, the
13830 6e 20 61 6c 6c 20 74 68 65 20 72 68 73 20 73 75  n all the rhs su
13840 62 2d 63 75 72 73 6f 72 73 20 6d 75 73 74 20 62  b-cursors must b
13850 65 20 61 74 20 45 4f 46 2e 20 0a 20 20 2a 2a 0a  e at EOF. .  **.
13860 20 20 2a 2a 20 41 6c 73 6f 20 61 73 73 65 72 74    ** Also assert
13870 20 74 68 61 74 20 61 6c 6c 20 72 68 73 20 73 75   that all rhs su
13880 62 2d 63 75 72 73 6f 72 73 20 61 72 65 20 65 69  b-cursors are ei
13890 74 68 65 72 20 61 74 20 45 4f 46 20 6f 72 20 70  ther at EOF or p
138a0 6f 69 6e 74 20 74 6f 0a 20 20 2a 2a 20 61 20 6b  oint to.  ** a k
138b0 65 79 20 74 68 61 74 20 69 73 20 6e 6f 74 20 6c  ey that is not l
138c0 65 73 73 20 74 68 61 6e 20 74 68 65 20 6c 65 76  ess than the lev
138d0 65 6c 20 73 70 6c 69 74 2d 6b 65 79 2e 20 20 2a  el split-key.  *
138e0 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70  /.  for(i=0; i<p
138f0 43 73 72 2d 3e 6e 50 74 72 3b 20 69 2b 2b 29 7b  Csr->nPtr; i++){
13900 0a 20 20 20 20 53 65 67 6d 65 6e 74 50 74 72 20  .    SegmentPtr 
13910 2a 70 50 74 72 20 3d 20 26 70 43 73 72 2d 3e 61  *pPtr = &pCsr->a
13920 50 74 72 5b 69 5d 3b 0a 20 20 20 20 4c 65 76 65  Ptr[i];.    Leve
13930 6c 20 2a 70 4c 76 6c 20 3d 20 70 50 74 72 2d 3e  l *pLvl = pPtr->
13940 70 4c 65 76 65 6c 3b 0a 20 20 20 20 69 66 28 20  pLevel;.    if( 
13950 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 20 26 26 20  pLvl->nRight && 
13960 70 50 74 72 2d 3e 70 50 67 20 29 7b 0a 20 20 20  pPtr->pPg ){.   
13970 20 20 20 69 66 28 20 70 50 74 72 2d 3e 70 53 65     if( pPtr->pSe
13980 67 3d 3d 26 70 4c 76 6c 2d 3e 6c 68 73 20 29 7b  g==&pLvl->lhs ){
13990 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6a 3b 0a  .        int j;.
139a0 20 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b          for(j=0;
139b0 20 6a 3c 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 3b   j<pLvl->nRight;
139c0 20 6a 2b 2b 29 20 61 73 73 65 72 74 28 20 70 50   j++) assert( pP
139d0 74 72 5b 6a 2b 31 5d 2e 70 50 67 3d 3d 30 20 29  tr[j+1].pPg==0 )
139e0 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
139f0 20 20 20 20 20 20 20 69 6e 74 20 72 65 73 20 3d         int res =
13a00 20 73 6f 72 74 65 64 4b 65 79 43 6f 6d 70 61 72   sortedKeyCompar
13a10 65 28 70 43 73 72 2d 3e 70 44 62 2d 3e 78 43 6d  e(pCsr->pDb->xCm
13a20 70 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20  p, .            
13a30 72 74 54 6f 70 69 63 28 70 50 74 72 2d 3e 65 54  rtTopic(pPtr->eT
13a40 79 70 65 29 2c 20 70 50 74 72 2d 3e 70 4b 65 79  ype), pPtr->pKey
13a50 2c 20 70 50 74 72 2d 3e 6e 4b 65 79 2c 0a 20 20  , pPtr->nKey,.  
13a60 20 20 20 20 20 20 20 20 20 20 70 4c 76 6c 2d 3e            pLvl->
13a70 69 53 70 6c 69 74 54 6f 70 69 63 2c 20 70 4c 76  iSplitTopic, pLv
13a80 6c 2d 3e 70 53 70 6c 69 74 4b 65 79 2c 20 70 4c  l->pSplitKey, pL
13a90 76 6c 2d 3e 6e 53 70 6c 69 74 4b 65 79 0a 20 20  vl->nSplitKey.  
13aa0 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20        );.       
13ab0 20 61 73 73 65 72 74 28 20 72 65 73 3e 3d 30 20   assert( res>=0 
13ac0 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
13ad0 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2f  .  }.#endif..  /
13ae0 2a 20 4e 6f 77 20 63 68 65 63 6b 20 69 66 20 74  * Now check if t
13af0 68 69 73 20 6b 65 79 20 68 61 73 20 61 6c 72 65  his key has alre
13b00 61 64 79 20 62 65 65 6e 20 64 65 6c 65 74 65 64  ady been deleted
13b10 20 62 79 20 61 20 72 61 6e 67 65 2d 64 65 6c 65   by a range-dele
13b20 74 65 2e 20 49 66 20 0a 20 20 2a 2a 20 73 6f 2c  te. If .  ** so,
13b30 20 73 6b 69 70 20 70 61 73 74 20 69 74 2e 0a 20   skip past it.. 
13b40 20 2a 2a 0a 20 20 2a 2a 20 41 73 73 75 6d 65 2c   **.  ** Assume,
13b50 20 66 6f 72 20 74 68 65 20 6d 6f 6d 65 6e 74 2c   for the moment,
13b60 20 74 68 61 74 20 74 68 65 20 74 72 65 65 20 63   that the tree c
13b70 6f 6e 74 61 69 6e 73 20 6e 6f 20 6c 65 76 65 6c  ontains no level
13b80 73 20 63 75 72 72 65 6e 74 6c 79 20 0a 20 20 2a  s currently .  *
13b90 2a 20 75 6e 64 65 72 67 6f 69 6e 67 20 69 6e 63  * undergoing inc
13ba0 72 65 6d 65 6e 74 61 6c 20 6d 65 72 67 65 2c 20  remental merge, 
13bb0 61 6e 64 20 74 68 61 74 20 74 68 69 73 20 63 75  and that this cu
13bc0 72 73 6f 72 20 69 73 20 69 74 65 72 61 74 69 6e  rsor is iteratin
13bd0 67 20 66 6f 72 77 61 72 64 73 0a 20 20 2a 2a 20  g forwards.  ** 
13be0 74 68 72 6f 75 67 68 20 74 68 65 20 64 61 74 61  through the data
13bf0 62 61 73 65 20 6b 65 79 73 2e 20 54 68 65 20 63  base keys. The c
13c00 75 72 73 6f 72 20 63 75 72 72 65 6e 74 6c 79 20  ursor currently 
13c10 70 6f 69 6e 74 73 20 74 6f 20 61 20 6b 65 79 20  points to a key 
13c20 69 6e 0a 20 20 2a 2a 20 6c 65 76 65 6c 20 4c 2e  in.  ** level L.
13c30 20 54 68 69 73 20 6b 65 79 20 68 61 73 20 61 6c   This key has al
13c40 72 65 61 64 79 20 62 65 65 6e 20 64 65 6c 65 74  ready been delet
13c50 65 64 20 69 66 20 61 6e 79 20 6f 66 20 74 68 65  ed if any of the
13c60 20 73 75 62 2d 63 75 72 73 6f 72 73 0a 20 20 2a   sub-cursors.  *
13c70 2a 20 74 68 61 74 20 70 6f 69 6e 74 20 74 6f 20  * that point to 
13c80 6c 65 76 65 6c 73 20 6e 65 77 65 72 20 74 68 61  levels newer tha
13c90 6e 20 4c 20 28 6f 72 20 74 6f 20 74 68 65 20 69  n L (or to the i
13ca0 6e 2d 6d 65 6d 6f 72 79 20 74 72 65 65 29 20 70  n-memory tree) p
13cb0 6f 69 6e 74 20 74 6f 0a 20 20 2a 2a 20 61 20 6b  oint to.  ** a k
13cc0 65 79 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  ey greater than 
13cd0 74 68 65 20 63 75 72 72 65 6e 74 20 6b 65 79 20  the current key 
13ce0 77 69 74 68 20 74 68 65 20 4c 53 4d 5f 45 4e 44  with the LSM_END
13cf0 5f 44 45 4c 45 54 45 20 66 6c 61 67 20 73 65 74  _DELETE flag set
13d00 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 4f 72 2c 20  ..  **.  ** Or, 
13d10 69 66 20 74 68 65 20 63 75 72 73 6f 72 20 69 73  if the cursor is
13d20 20 69 74 65 72 61 74 69 6e 67 20 62 61 63 6b 77   iterating backw
13d30 61 72 64 73 20 74 68 72 6f 75 67 68 20 64 61 74  ards through dat
13d40 61 20 6b 65 79 73 2c 20 69 66 20 61 6e 79 0a 20  a keys, if any. 
13d50 20 2a 2a 20 73 75 63 68 20 73 75 62 2d 63 75 72   ** such sub-cur
13d60 73 6f 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20  sor points to a 
13d70 6b 65 79 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e  key smaller than
13d80 20 74 68 65 20 63 75 72 72 65 6e 74 20 6b 65 79   the current key
13d90 20 77 69 74 68 20 74 68 65 0a 20 20 2a 2a 20 4c   with the.  ** L
13da0 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45 54 45 20  SM_START_DELETE 
13db0 66 6c 61 67 20 73 65 74 2e 0a 20 20 2a 2a 0a 20  flag set..  **. 
13dc0 20 2a 2a 20 57 68 79 20 69 74 20 77 6f 72 6b 73   ** Why it works
13dd0 20 77 69 74 68 20 6c 65 76 65 6c 73 20 75 6e 64   with levels und
13de0 65 72 67 6f 69 6e 67 20 61 20 6d 65 72 67 65 20  ergoing a merge 
13df0 74 6f 6f 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 57  too:.  **.  ** W
13e00 68 65 6e 20 61 20 63 75 72 73 6f 72 20 69 74 65  hen a cursor ite
13e10 72 61 74 65 73 20 66 6f 72 77 61 72 64 73 2c 20  rates forwards, 
13e20 74 68 65 20 73 75 62 2d 63 75 72 73 6f 72 73 20  the sub-cursors 
13e30 66 6f 72 20 74 68 65 20 72 68 73 20 6f 66 20 61  for the rhs of a
13e40 20 0a 20 20 2a 2a 20 6c 65 76 65 6c 20 61 72 65   .  ** level are
13e50 20 6f 6e 6c 79 20 61 63 74 69 76 61 74 65 64 20   only activated 
13e60 6f 6e 63 65 20 74 68 65 20 6c 68 73 20 72 65 61  once the lhs rea
13e70 63 68 65 73 20 45 4f 46 2e 20 53 6f 20 77 68 65  ches EOF. So whe
13e80 6e 20 69 74 65 72 61 74 69 6e 67 0a 20 20 2a 2a  n iterating.  **
13e90 20 66 6f 72 77 61 72 64 73 2c 20 74 68 65 20 6b   forwards, the k
13ea0 65 79 73 20 76 69 73 69 74 65 64 20 61 72 65 20  eys visited are 
13eb0 74 68 65 20 73 61 6d 65 20 61 73 20 69 66 20 74  the same as if t
13ec0 68 65 20 6c 65 76 65 6c 20 77 61 73 20 63 6f 6d  he level was com
13ed0 70 6c 65 74 65 6c 79 0a 20 20 2a 2a 20 6d 65 72  pletely.  ** mer
13ee0 67 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49  ged..  **.  ** I
13ef0 66 20 74 68 65 20 63 75 72 73 6f 72 20 69 73 20  f the cursor is 
13f00 69 74 65 72 61 74 69 6e 67 20 62 61 63 6b 77 61  iterating backwa
13f10 72 64 73 2c 20 74 68 65 6e 20 74 68 65 20 6c 68  rds, then the lh
13f20 73 20 73 75 62 2d 63 75 72 73 6f 72 20 69 73 20  s sub-cursor is 
13f30 6e 6f 74 20 0a 20 20 2a 2a 20 69 6e 69 74 69 61  not .  ** initia
13f40 6c 69 7a 65 64 20 75 6e 74 69 6c 20 74 68 65 20  lized until the 
13f50 6c 61 73 74 20 6f 66 20 74 68 65 20 72 68 73 20  last of the rhs 
13f60 73 75 62 2d 63 75 72 73 6f 72 73 20 68 61 73 20  sub-cursors has 
13f70 72 65 61 63 68 65 64 20 45 4f 46 2e 0a 20 20 2a  reached EOF..  *
13f80 2a 20 41 64 64 69 74 69 6f 6e 61 6c 6c 79 2c 20  * Additionally, 
13f90 69 66 20 74 68 65 20 53 54 41 52 54 5f 44 45 4c  if the START_DEL
13fa0 45 54 45 20 66 6c 61 67 20 69 73 20 73 65 74 20  ETE flag is set 
13fb0 6f 6e 20 74 68 65 20 6c 61 73 74 20 65 6e 74 72  on the last entr
13fc0 79 20 28 69 6e 0a 20 20 2a 2a 20 72 65 76 65 72  y (in.  ** rever
13fd0 73 65 20 6f 72 64 65 72 20 2d 20 73 6f 20 74 68  se order - so th
13fe0 65 20 65 6e 74 72 79 20 77 69 74 68 20 74 68 65  e entry with the
13ff0 20 73 6d 61 6c 6c 65 73 74 20 6b 65 79 29 20 6f   smallest key) o
14000 66 20 61 20 72 68 73 20 73 75 62 2d 63 75 72 73  f a rhs sub-curs
14010 6f 72 2c 0a 20 20 2a 2a 20 74 68 65 6e 20 61 20  or,.  ** then a 
14020 70 73 65 75 64 6f 2d 6b 65 79 20 65 71 75 61 6c  pseudo-key equal
14030 20 74 6f 20 74 68 65 20 6c 65 76 65 6c 73 20 73   to the levels s
14040 70 6c 69 74 2d 6b 65 79 20 77 69 74 68 20 74 68  plit-key with th
14050 65 20 45 4e 44 5f 44 45 4c 45 54 45 0a 20 20 2a  e END_DELETE.  *
14060 2a 20 66 6c 61 67 20 73 65 74 20 69 73 20 76 69  * flag set is vi
14070 73 69 74 65 64 20 62 79 20 74 68 65 20 73 75 62  sited by the sub
14080 2d 63 75 72 73 6f 72 2e 0a 20 20 2a 2f 20 0a 20  -cursor..  */ . 
14090 20 69 4b 65 79 20 3d 20 70 43 73 72 2d 3e 61 54   iKey = pCsr->aT
140a0 72 65 65 5b 31 5d 3b 0a 20 20 66 6f 72 28 69 3d  ree[1];.  for(i=
140b0 30 3b 20 69 3c 69 4b 65 79 3b 20 69 2b 2b 29 7b  0; i<iKey; i++){
140c0 0a 20 20 20 20 69 6e 74 20 63 73 72 66 6c 61 67  .    int csrflag
140d0 73 3b 0a 20 20 20 20 6d 75 6c 74 69 43 75 72 73  s;.    multiCurs
140e0 6f 72 47 65 74 4b 65 79 28 70 43 73 72 2c 20 69  orGetKey(pCsr, i
140f0 2c 20 26 63 73 72 66 6c 61 67 73 2c 20 30 2c 20  , &csrflags, 0, 
14100 30 29 3b 0a 20 20 20 20 69 66 28 20 28 72 64 6d  0);.    if( (rdm
14110 61 73 6b 20 26 20 63 73 72 66 6c 61 67 73 29 20  ask & csrflags) 
14120 29 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 69  ){.      const i
14130 6e 74 20 53 44 5f 45 44 20 3d 20 28 4c 53 4d 5f  nt SD_ED = (LSM_
14140 53 54 41 52 54 5f 44 45 4c 45 54 45 7c 4c 53 4d  START_DELETE|LSM
14150 5f 45 4e 44 5f 44 45 4c 45 54 45 29 3b 0a 20 20  _END_DELETE);.  
14160 20 20 20 20 69 66 28 20 28 63 73 72 66 6c 61 67      if( (csrflag
14170 73 20 26 20 53 44 5f 45 44 29 3d 3d 53 44 5f 45  s & SD_ED)==SD_E
14180 44 20 0a 20 20 20 20 20 20 20 7c 7c 20 28 70 43  D .       || (pC
14190 73 72 2d 3e 66 6c 61 67 73 20 26 20 43 55 52 53  sr->flags & CURS
141a0 4f 52 5f 49 47 4e 4f 52 45 5f 44 45 4c 45 54 45  OR_IGNORE_DELETE
141b0 29 3d 3d 30 0a 20 20 20 20 20 20 29 7b 0a 20 20  )==0.      ){.  
141c0 20 20 20 20 20 20 76 6f 69 64 20 2a 70 4b 65 79        void *pKey
141d0 3b 20 69 6e 74 20 6e 4b 65 79 3b 0a 20 20 20 20  ; int nKey;.    
141e0 20 20 20 20 6d 75 6c 74 69 43 75 72 73 6f 72 47      multiCursorG
141f0 65 74 4b 65 79 28 70 43 73 72 2c 20 69 2c 20 30  etKey(pCsr, i, 0
14200 2c 20 26 70 4b 65 79 2c 20 26 6e 4b 65 79 29 3b  , &pKey, &nKey);
14210 0a 20 20 20 20 20 20 20 20 69 66 28 20 30 3d 3d  .        if( 0==
14220 73 6f 72 74 65 64 4b 65 79 43 6f 6d 70 61 72 65  sortedKeyCompare
14230 28 70 43 73 72 2d 3e 70 44 62 2d 3e 78 43 6d 70  (pCsr->pDb->xCmp
14240 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
14250 72 74 54 6f 70 69 63 28 65 54 79 70 65 29 2c 20  rtTopic(eType), 
14260 70 43 73 72 2d 3e 6b 65 79 2e 70 44 61 74 61 2c  pCsr->key.pData,
14270 20 70 43 73 72 2d 3e 6b 65 79 2e 6e 44 61 74 61   pCsr->key.nData
14280 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
14290 72 74 54 6f 70 69 63 28 63 73 72 66 6c 61 67 73  rtTopic(csrflags
142a0 29 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 0a 20 20  ), pKey, nKey.  
142b0 20 20 20 20 20 20 29 29 7b 0a 20 20 20 20 20 20        )){.      
142c0 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20      continue;.  
142d0 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
142e0 20 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a        return 0;.
142f0 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20      }.  }..  /* 
14300 54 68 65 20 63 75 72 72 65 6e 74 20 63 75 72 73  The current curs
14310 6f 72 20 70 6f 73 69 74 69 6f 6e 20 69 73 20 6f  or position is o
14320 6e 65 20 74 68 69 73 20 63 75 72 73 6f 72 20 73  ne this cursor s
14330 68 6f 75 6c 64 20 76 69 73 69 74 2e 20 52 65 74  hould visit. Ret
14340 75 72 6e 20 31 2e 20 2a 2f 0a 20 20 72 65 74 75  urn 1. */.  retu
14350 72 6e 20 31 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  rn 1;.}..static 
14360 69 6e 74 20 6d 75 6c 74 69 43 75 72 73 6f 72 53  int multiCursorS
14370 65 74 75 70 54 72 65 65 28 4d 75 6c 74 69 43 75  etupTree(MultiCu
14380 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74 20  rsor *pCsr, int 
14390 62 52 65 76 29 7b 0a 20 20 69 6e 74 20 72 63 3b  bRev){.  int rc;
143a0 0a 0a 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75  ..  rc = multiCu
143b0 72 73 6f 72 41 6c 6c 6f 63 54 72 65 65 28 70 43  rsorAllocTree(pC
143c0 73 72 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 4c  sr);.  if( rc==L
143d0 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74  SM_OK ){.    int
143e0 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 70 43   i;.    for(i=pC
143f0 73 72 2d 3e 6e 54 72 65 65 2d 31 3b 20 69 3e 30  sr->nTree-1; i>0
14400 3b 20 69 2d 2d 29 7b 0a 20 20 20 20 20 20 6d 75  ; i--){.      mu
14410 6c 74 69 43 75 72 73 6f 72 44 6f 43 6f 6d 70 61  ltiCursorDoCompa
14420 72 65 28 70 43 73 72 2c 20 69 2c 20 62 52 65 76  re(pCsr, i, bRev
14430 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
14440 61 73 73 65 72 74 43 75 72 73 6f 72 54 72 65 65  assertCursorTree
14450 28 70 43 73 72 29 3b 0a 20 20 6d 75 6c 74 69 43  (pCsr);.  multiC
14460 75 72 73 6f 72 43 61 63 68 65 4b 65 79 28 70 43  ursorCacheKey(pC
14470 73 72 2c 20 26 72 63 29 3b 0a 0a 20 20 69 66 28  sr, &rc);..  if(
14480 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 6d   rc==LSM_OK && m
14490 63 75 72 73 6f 72 4c 6f 63 61 74 69 6f 6e 4f 6b  cursorLocationOk
144a0 28 70 43 73 72 2c 20 30 29 3d 3d 30 20 29 7b 0a  (pCsr, 0)==0 ){.
144b0 20 20 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75      rc = multiCu
144c0 72 73 6f 72 41 64 76 61 6e 63 65 28 70 43 73 72  rsorAdvance(pCsr
144d0 2c 20 62 52 65 76 29 3b 0a 20 20 7d 0a 20 20 72  , bRev);.  }.  r
144e0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 73 74  eturn rc;.}...st
144f0 61 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 43 75  atic int multiCu
14500 72 73 6f 72 45 6e 64 28 4d 75 6c 74 69 43 75 72  rsorEnd(MultiCur
14510 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74 20 62  sor *pCsr, int b
14520 4c 61 73 74 29 7b 0a 20 20 69 6e 74 20 72 63 20  Last){.  int rc 
14530 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 69 6e 74 20  = LSM_OK;.  int 
14540 69 3b 0a 0a 20 20 70 43 73 72 2d 3e 66 6c 61 67  i;..  pCsr->flag
14550 73 20 26 3d 20 7e 28 43 55 52 53 4f 52 5f 4e 45  s &= ~(CURSOR_NE
14560 58 54 5f 4f 4b 20 7c 20 43 55 52 53 4f 52 5f 50  XT_OK | CURSOR_P
14570 52 45 56 5f 4f 4b 20 7c 20 43 55 52 53 4f 52 5f  REV_OK | CURSOR_
14580 53 45 45 4b 5f 45 51 29 3b 0a 20 20 70 43 73 72  SEEK_EQ);.  pCsr
14590 2d 3e 66 6c 61 67 73 20 7c 3d 20 28 62 4c 61 73  ->flags |= (bLas
145a0 74 20 3f 20 43 55 52 53 4f 52 5f 50 52 45 56 5f  t ? CURSOR_PREV_
145b0 4f 4b 20 3a 20 43 55 52 53 4f 52 5f 4e 45 58 54  OK : CURSOR_NEXT
145c0 5f 4f 4b 29 3b 0a 20 20 70 43 73 72 2d 3e 69 46  _OK);.  pCsr->iF
145d0 72 65 65 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 50  ree = 0;..  /* P
145e0 6f 73 69 74 69 6f 6e 20 74 68 65 20 74 77 6f 20  osition the two 
145f0 69 6e 2d 6d 65 6d 6f 72 79 20 74 72 65 65 20 63  in-memory tree c
14600 75 72 73 6f 72 73 20 2a 2f 0a 20 20 66 6f 72 28  ursors */.  for(
14610 69 3d 30 3b 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20  i=0; rc==LSM_OK 
14620 26 26 20 69 3c 32 3b 20 69 2b 2b 29 7b 0a 20 20  && i<2; i++){.  
14630 20 20 69 66 28 20 70 43 73 72 2d 3e 61 70 54 72    if( pCsr->apTr
14640 65 65 43 73 72 5b 69 5d 20 29 7b 0a 20 20 20 20  eeCsr[i] ){.    
14650 20 20 72 63 20 3d 20 6c 73 6d 54 72 65 65 43 75    rc = lsmTreeCu
14660 72 73 6f 72 45 6e 64 28 70 43 73 72 2d 3e 61 70  rsorEnd(pCsr->ap
14670 54 72 65 65 43 73 72 5b 69 5d 2c 20 62 4c 61 73  TreeCsr[i], bLas
14680 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  t);.    }.  }.. 
14690 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 4c 53   for(i=0; rc==LS
146a0 4d 5f 4f 4b 20 26 26 20 69 3c 70 43 73 72 2d 3e  M_OK && i<pCsr->
146b0 6e 50 74 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nPtr; i++){.    
146c0 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72  SegmentPtr *pPtr
146d0 20 3d 20 26 70 43 73 72 2d 3e 61 50 74 72 5b 69   = &pCsr->aPtr[i
146e0 5d 3b 0a 20 20 20 20 4c 65 76 65 6c 20 2a 70 4c  ];.    Level *pL
146f0 76 6c 20 3d 20 70 50 74 72 2d 3e 70 4c 65 76 65  vl = pPtr->pLeve
14700 6c 3b 0a 20 20 20 20 69 6e 74 20 69 52 68 73 3b  l;.    int iRhs;
14710 0a 20 20 20 20 69 6e 74 20 62 48 69 74 20 3d 20  .    int bHit = 
14720 30 3b 0a 0a 20 20 20 20 69 66 28 20 62 4c 61 73  0;..    if( bLas
14730 74 20 29 7b 0a 20 20 20 20 20 20 66 6f 72 28 69  t ){.      for(i
14740 52 68 73 3d 30 3b 20 69 52 68 73 3c 70 4c 76 6c  Rhs=0; iRhs<pLvl
14750 2d 3e 6e 52 69 67 68 74 20 26 26 20 72 63 3d 3d  ->nRight && rc==
14760 4c 53 4d 5f 4f 4b 3b 20 69 52 68 73 2b 2b 29 7b  LSM_OK; iRhs++){
14770 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65  .        rc = se
14780 67 6d 65 6e 74 50 74 72 45 6e 64 28 70 43 73 72  gmentPtrEnd(pCsr
14790 2c 20 26 70 50 74 72 5b 69 52 68 73 2b 31 5d 2c  , &pPtr[iRhs+1],
147a0 20 31 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28   1);.        if(
147b0 20 70 50 74 72 5b 69 52 68 73 2b 31 5d 2e 70 50   pPtr[iRhs+1].pP
147c0 67 20 29 20 62 48 69 74 20 3d 20 31 3b 0a 20 20  g ) bHit = 1;.  
147d0 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
147e0 62 48 69 74 3d 3d 30 20 26 26 20 72 63 3d 3d 4c  bHit==0 && rc==L
147f0 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  SM_OK ){.       
14800 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74 72   rc = segmentPtr
14810 45 6e 64 28 70 43 73 72 2c 20 70 50 74 72 2c 20  End(pCsr, pPtr, 
14820 31 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  1);.      }else{
14830 0a 20 20 20 20 20 20 20 20 73 65 67 6d 65 6e 74  .        segment
14840 50 74 72 52 65 73 65 74 28 70 50 74 72 2c 20 4c  PtrReset(pPtr, L
14850 53 4d 5f 53 45 47 4d 45 4e 54 50 54 52 5f 46 52  SM_SEGMENTPTR_FR
14860 45 45 5f 54 48 52 45 53 48 4f 4c 44 29 3b 0a 20  EE_THRESHOLD);. 
14870 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65       }.    }else
14880 7b 0a 20 20 20 20 20 20 69 6e 74 20 62 4c 68 73  {.      int bLhs
14890 20 3d 20 28 70 50 74 72 2d 3e 70 53 65 67 3d 3d   = (pPtr->pSeg==
148a0 26 70 4c 76 6c 2d 3e 6c 68 73 29 3b 0a 20 20 20  &pLvl->lhs);.   
148b0 20 20 20 61 73 73 65 72 74 28 20 70 50 74 72 2d     assert( pPtr-
148c0 3e 70 53 65 67 3d 3d 26 70 4c 76 6c 2d 3e 6c 68  >pSeg==&pLvl->lh
148d0 73 20 7c 7c 20 70 50 74 72 2d 3e 70 53 65 67 3d  s || pPtr->pSeg=
148e0 3d 26 70 4c 76 6c 2d 3e 61 52 68 73 5b 30 5d 20  =&pLvl->aRhs[0] 
148f0 29 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 62 4c  );..      if( bL
14900 68 73 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63  hs ){.        rc
14910 20 3d 20 73 65 67 6d 65 6e 74 50 74 72 45 6e 64   = segmentPtrEnd
14920 28 70 43 73 72 2c 20 70 50 74 72 2c 20 30 29 3b  (pCsr, pPtr, 0);
14930 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 50 74  .        if( pPt
14940 72 2d 3e 70 4b 65 79 20 29 20 62 48 69 74 20 3d  r->pKey ) bHit =
14950 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20   1;.      }.    
14960 20 20 66 6f 72 28 69 52 68 73 3d 30 3b 20 69 52    for(iRhs=0; iR
14970 68 73 3c 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 20  hs<pLvl->nRight 
14980 26 26 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 3b 20 69  && rc==LSM_OK; i
14990 52 68 73 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  Rhs++){.        
149a0 69 66 28 20 62 48 69 74 20 29 7b 0a 20 20 20 20  if( bHit ){.    
149b0 20 20 20 20 20 20 73 65 67 6d 65 6e 74 50 74 72        segmentPtr
149c0 52 65 73 65 74 28 26 70 50 74 72 5b 69 52 68 73  Reset(&pPtr[iRhs
149d0 2b 31 5d 2c 20 4c 53 4d 5f 53 45 47 4d 45 4e 54  +1], LSM_SEGMENT
149e0 50 54 52 5f 46 52 45 45 5f 54 48 52 45 53 48 4f  PTR_FREE_THRESHO
149f0 4c 44 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  LD);.        }el
14a00 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63  se{.          rc
14a10 20 3d 20 73 6f 72 74 65 64 52 68 73 46 69 72 73   = sortedRhsFirs
14a20 74 28 70 43 73 72 2c 20 70 4c 76 6c 2c 20 26 70  t(pCsr, pLvl, &p
14a30 50 74 72 5b 69 52 68 73 2b 62 4c 68 73 5d 29 3b  Ptr[iRhs+bLhs]);
14a40 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
14a50 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 20 2b   }.    }.    i +
14a60 3d 20 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 3b 0a  = pLvl->nRight;.
14a70 20 20 7d 0a 0a 20 20 2f 2a 20 41 6e 64 20 74 68    }..  /* And th
14a80 65 20 62 2d 74 72 65 65 20 63 75 72 73 6f 72 2c  e b-tree cursor,
14a90 20 69 66 20 61 70 70 6c 69 63 61 62 6c 65 20 2a   if applicable *
14aa0 2f 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f  /.  if( rc==LSM_
14ab0 4f 4b 20 26 26 20 70 43 73 72 2d 3e 70 42 74 43  OK && pCsr->pBtC
14ac0 73 72 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74  sr ){.    assert
14ad0 28 20 62 4c 61 73 74 3d 3d 30 20 29 3b 0a 20 20  ( bLast==0 );.  
14ae0 20 20 72 63 20 3d 20 62 74 72 65 65 43 75 72 73    rc = btreeCurs
14af0 6f 72 46 69 72 73 74 28 70 43 73 72 2d 3e 70 42  orFirst(pCsr->pB
14b00 74 43 73 72 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  tCsr);.  }..  if
14b10 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a  ( rc==LSM_OK ){.
14b20 20 20 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75      rc = multiCu
14b30 72 73 6f 72 53 65 74 75 70 54 72 65 65 28 70 43  rsorSetupTree(pC
14b40 73 72 2c 20 62 4c 61 73 74 29 3b 0a 20 20 7d 0a  sr, bLast);.  }.
14b50 20 20 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a    .  return rc;.
14b60 7d 0a 0a 0a 69 6e 74 20 6d 63 75 72 73 6f 72 53  }...int mcursorS
14b70 61 76 65 28 4d 75 6c 74 69 43 75 72 73 6f 72 20  ave(MultiCursor 
14b80 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74 20 72 63  *pCsr){.  int rc
14b90 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 69 66 28   = LSM_OK;.  if(
14ba0 20 70 43 73 72 2d 3e 61 54 72 65 65 20 29 7b 0a   pCsr->aTree ){.
14bb0 20 20 20 20 69 6e 74 20 69 54 72 65 65 20 3d 20      int iTree = 
14bc0 70 43 73 72 2d 3e 61 54 72 65 65 5b 31 5d 3b 0a  pCsr->aTree[1];.
14bd0 20 20 20 20 69 66 28 20 69 54 72 65 65 3d 3d 43      if( iTree==C
14be0 55 52 53 4f 52 5f 44 41 54 41 5f 54 52 45 45 30  URSOR_DATA_TREE0
14bf0 20 7c 7c 20 69 54 72 65 65 3d 3d 43 55 52 53 4f   || iTree==CURSO
14c00 52 5f 44 41 54 41 5f 54 52 45 45 31 20 29 7b 0a  R_DATA_TREE1 ){.
14c10 20 20 20 20 20 20 6d 75 6c 74 69 43 75 72 73 6f        multiCurso
14c20 72 43 61 63 68 65 4b 65 79 28 70 43 73 72 2c 20  rCacheKey(pCsr, 
14c30 26 72 63 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  &rc);.    }.  }.
14c40 20 20 6d 63 75 72 73 6f 72 46 72 65 65 43 6f 6d    mcursorFreeCom
14c50 70 6f 6e 65 6e 74 73 28 70 43 73 72 29 3b 0a 20  ponents(pCsr);. 
14c60 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69   return rc;.}..i
14c70 6e 74 20 6d 63 75 72 73 6f 72 52 65 73 74 6f 72  nt mcursorRestor
14c80 65 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 4d  e(lsm_db *pDb, M
14c90 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72  ultiCursor *pCsr
14ca0 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 72  ){.  int rc;.  r
14cb0 63 20 3d 20 6d 75 6c 74 69 43 75 72 73 6f 72 49  c = multiCursorI
14cc0 6e 69 74 28 70 43 73 72 2c 20 70 44 62 2d 3e 70  nit(pCsr, pDb->p
14cd0 43 6c 69 65 6e 74 29 3b 0a 20 20 69 66 28 20 72  Client);.  if( r
14ce0 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 43 73  c==LSM_OK && pCs
14cf0 72 2d 3e 6b 65 79 2e 70 44 61 74 61 20 29 7b 0a  r->key.pData ){.
14d00 20 20 20 20 72 63 20 3d 20 6c 73 6d 4d 43 75 72      rc = lsmMCur
14d10 73 6f 72 53 65 65 6b 28 70 43 73 72 2c 20 0a 20  sorSeek(pCsr, . 
14d20 20 20 20 20 20 20 20 20 72 74 54 6f 70 69 63 28          rtTopic(
14d30 70 43 73 72 2d 3e 65 54 79 70 65 29 2c 20 70 43  pCsr->eType), pC
14d40 73 72 2d 3e 6b 65 79 2e 70 44 61 74 61 2c 20 70  sr->key.pData, p
14d50 43 73 72 2d 3e 6b 65 79 2e 6e 44 61 74 61 2c 20  Csr->key.nData, 
14d60 2b 31 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 20 20  +1.    );.  }.  
14d70 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e  return rc;.}..in
14d80 74 20 6c 73 6d 53 61 76 65 43 75 72 73 6f 72 73  t lsmSaveCursors
14d90 28 6c 73 6d 5f 64 62 20 2a 70 44 62 29 7b 0a 20  (lsm_db *pDb){. 
14da0 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
14db0 3b 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  ;.  MultiCursor 
14dc0 2a 70 43 73 72 3b 0a 0a 20 20 66 6f 72 28 70 43  *pCsr;..  for(pC
14dd0 73 72 3d 70 44 62 2d 3e 70 43 73 72 3b 20 72 63  sr=pDb->pCsr; rc
14de0 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 43 73 72  ==LSM_OK && pCsr
14df0 3b 20 70 43 73 72 3d 70 43 73 72 2d 3e 70 4e 65  ; pCsr=pCsr->pNe
14e00 78 74 29 7b 0a 20 20 20 20 72 63 20 3d 20 6d 63  xt){.    rc = mc
14e10 75 72 73 6f 72 53 61 76 65 28 70 43 73 72 29 3b  ursorSave(pCsr);
14e20 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
14e30 3b 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 52 65 73 74  ;.}..int lsmRest
14e40 6f 72 65 43 75 72 73 6f 72 73 28 6c 73 6d 5f 64  oreCursors(lsm_d
14e50 62 20 2a 70 44 62 29 7b 0a 20 20 69 6e 74 20 72  b *pDb){.  int r
14e60 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 4d 75  c = LSM_OK;.  Mu
14e70 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 3b  ltiCursor *pCsr;
14e80 0a 0a 20 20 66 6f 72 28 70 43 73 72 3d 70 44 62  ..  for(pCsr=pDb
14e90 2d 3e 70 43 73 72 3b 20 72 63 3d 3d 4c 53 4d 5f  ->pCsr; rc==LSM_
14ea0 4f 4b 20 26 26 20 70 43 73 72 3b 20 70 43 73 72  OK && pCsr; pCsr
14eb0 3d 70 43 73 72 2d 3e 70 4e 65 78 74 29 7b 0a 20  =pCsr->pNext){. 
14ec0 20 20 20 72 63 20 3d 20 6d 63 75 72 73 6f 72 52     rc = mcursorR
14ed0 65 73 74 6f 72 65 28 70 44 62 2c 20 70 43 73 72  estore(pDb, pCsr
14ee0 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
14ef0 72 63 3b 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 4d 43  rc;.}..int lsmMC
14f00 75 72 73 6f 72 46 69 72 73 74 28 4d 75 6c 74 69  ursorFirst(Multi
14f10 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20  Cursor *pCsr){. 
14f20 20 72 65 74 75 72 6e 20 6d 75 6c 74 69 43 75 72   return multiCur
14f30 73 6f 72 45 6e 64 28 70 43 73 72 2c 20 30 29 3b  sorEnd(pCsr, 0);
14f40 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 4d 43 75 72 73  .}..int lsmMCurs
14f50 6f 72 4c 61 73 74 28 4d 75 6c 74 69 43 75 72 73  orLast(MultiCurs
14f60 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 72 65 74  or *pCsr){.  ret
14f70 75 72 6e 20 6d 75 6c 74 69 43 75 72 73 6f 72 45  urn multiCursorE
14f80 6e 64 28 70 43 73 72 2c 20 31 29 3b 0a 7d 0a 0a  nd(pCsr, 1);.}..
14f90 6c 73 6d 5f 64 62 20 2a 6c 73 6d 4d 43 75 72 73  lsm_db *lsmMCurs
14fa0 6f 72 44 62 28 4d 75 6c 74 69 43 75 72 73 6f 72  orDb(MultiCursor
14fb0 20 2a 70 43 73 72 29 7b 0a 20 20 72 65 74 75 72   *pCsr){.  retur
14fc0 6e 20 70 43 73 72 2d 3e 70 44 62 3b 0a 7d 0a 0a  n pCsr->pDb;.}..
14fd0 76 6f 69 64 20 6c 73 6d 4d 43 75 72 73 6f 72 52  void lsmMCursorR
14fe0 65 73 65 74 28 4d 75 6c 74 69 43 75 72 73 6f 72  eset(MultiCursor
14ff0 20 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74 20 69   *pCsr){.  int i
15000 3b 0a 20 20 6c 73 6d 54 72 65 65 43 75 72 73 6f  ;.  lsmTreeCurso
15010 72 52 65 73 65 74 28 70 43 73 72 2d 3e 61 70 54  rReset(pCsr->apT
15020 72 65 65 43 73 72 5b 30 5d 29 3b 0a 20 20 6c 73  reeCsr[0]);.  ls
15030 6d 54 72 65 65 43 75 72 73 6f 72 52 65 73 65 74  mTreeCursorReset
15040 28 70 43 73 72 2d 3e 61 70 54 72 65 65 43 73 72  (pCsr->apTreeCsr
15050 5b 31 5d 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  [1]);.  for(i=0;
15060 20 69 3c 70 43 73 72 2d 3e 6e 50 74 72 3b 20 69   i<pCsr->nPtr; i
15070 2b 2b 29 7b 0a 20 20 20 20 73 65 67 6d 65 6e 74  ++){.    segment
15080 50 74 72 52 65 73 65 74 28 26 70 43 73 72 2d 3e  PtrReset(&pCsr->
15090 61 50 74 72 5b 69 5d 2c 20 4c 53 4d 5f 53 45 47  aPtr[i], LSM_SEG
150a0 4d 45 4e 54 50 54 52 5f 46 52 45 45 5f 54 48 52  MENTPTR_FREE_THR
150b0 45 53 48 4f 4c 44 29 3b 0a 20 20 7d 0a 20 20 70  ESHOLD);.  }.  p
150c0 43 73 72 2d 3e 6b 65 79 2e 6e 44 61 74 61 20 3d  Csr->key.nData =
150d0 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e   0;.}..static in
150e0 74 20 74 72 65 65 43 75 72 73 6f 72 53 65 65 6b  t treeCursorSeek
150f0 28 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  (.  MultiCursor 
15100 2a 70 43 73 72 2c 0a 20 20 54 72 65 65 43 75 72  *pCsr,.  TreeCur
15110 73 6f 72 20 2a 70 54 72 65 65 43 73 72 2c 20 0a  sor *pTreeCsr, .
15120 20 20 76 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e    void *pKey, in
15130 74 20 6e 4b 65 79 2c 20 0a 20 20 69 6e 74 20 65  t nKey, .  int e
15140 53 65 65 6b 2c 0a 20 20 69 6e 74 20 2a 70 62 53  Seek,.  int *pbS
15150 74 6f 70 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20  top.){.  int rc 
15160 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 69 66 28 20  = LSM_OK;.  if( 
15170 70 54 72 65 65 43 73 72 20 29 7b 0a 20 20 20 20  pTreeCsr ){.    
15180 69 6e 74 20 72 65 73 20 3d 20 30 3b 0a 20 20 20  int res = 0;.   
15190 20 6c 73 6d 54 72 65 65 43 75 72 73 6f 72 53 65   lsmTreeCursorSe
151a0 65 6b 28 70 54 72 65 65 43 73 72 2c 20 70 4b 65  ek(pTreeCsr, pKe
151b0 79 2c 20 6e 4b 65 79 2c 20 26 72 65 73 29 3b 0a  y, nKey, &res);.
151c0 20 20 20 20 73 77 69 74 63 68 28 20 65 53 65 65      switch( eSee
151d0 6b 20 29 7b 0a 20 20 20 20 20 20 63 61 73 65 20  k ){.      case 
151e0 4c 53 4d 5f 53 45 45 4b 5f 45 51 3a 20 7b 0a 20  LSM_SEEK_EQ: {. 
151f0 20 20 20 20 20 20 20 69 6e 74 20 65 54 79 70 65         int eType
15200 20 3d 20 6c 73 6d 54 72 65 65 43 75 72 73 6f 72   = lsmTreeCursor
15210 46 6c 61 67 73 28 70 54 72 65 65 43 73 72 29 3b  Flags(pTreeCsr);
15220 0a 20 20 20 20 20 20 20 20 69 66 28 20 28 72 65  .        if( (re
15230 73 3c 30 20 26 26 20 28 65 54 79 70 65 20 26 20  s<0 && (eType & 
15240 4c 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45 54 45  LSM_START_DELETE
15250 29 29 0a 20 20 20 20 20 20 20 20 20 7c 7c 20 28  )).         || (
15260 72 65 73 3e 30 20 26 26 20 28 65 54 79 70 65 20  res>0 && (eType 
15270 26 20 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45 54 45  & LSM_END_DELETE
15280 29 29 0a 20 20 20 20 20 20 20 20 20 7c 7c 20 28  )).         || (
15290 72 65 73 3d 3d 30 20 26 26 20 28 65 54 79 70 65  res==0 && (eType
152a0 20 26 20 4c 53 4d 5f 50 4f 49 4e 54 5f 44 45 4c   & LSM_POINT_DEL
152b0 45 54 45 29 29 0a 20 20 20 20 20 20 20 20 29 7b  ETE)).        ){
152c0 0a 20 20 20 20 20 20 20 20 20 20 2a 70 62 53 74  .          *pbSt
152d0 6f 70 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  op = 1;.        
152e0 7d 65 6c 73 65 20 69 66 28 20 72 65 73 3d 3d 30  }else if( res==0
152f0 20 26 26 20 28 65 54 79 70 65 20 26 20 4c 53 4d   && (eType & LSM
15300 5f 49 4e 53 45 52 54 29 20 29 7b 0a 20 20 20 20  _INSERT) ){.    
15310 20 20 20 20 20 20 6c 73 6d 5f 65 6e 76 20 2a 70        lsm_env *p
15320 45 6e 76 20 3d 20 70 43 73 72 2d 3e 70 44 62 2d  Env = pCsr->pDb-
15330 3e 70 45 6e 76 3b 0a 20 20 20 20 20 20 20 20 20  >pEnv;.         
15340 20 76 6f 69 64 20 2a 70 3b 20 69 6e 74 20 6e 3b   void *p; int n;
15350 20 20 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 2f           /* Key/
15360 76 61 6c 75 65 20 66 72 6f 6d 20 74 72 65 65 2d  value from tree-
15370 63 75 72 73 6f 72 20 2a 2f 0a 20 20 20 20 20 20  cursor */.      
15380 20 20 20 20 2a 70 62 53 74 6f 70 20 3d 20 31 3b      *pbStop = 1;
15390 0a 20 20 20 20 20 20 20 20 20 20 70 43 73 72 2d  .          pCsr-
153a0 3e 66 6c 61 67 73 20 7c 3d 20 43 55 52 53 4f 52  >flags |= CURSOR
153b0 5f 53 45 45 4b 5f 45 51 3b 0a 20 20 20 20 20 20  _SEEK_EQ;.      
153c0 20 20 20 20 72 63 20 3d 20 6c 73 6d 54 72 65 65      rc = lsmTree
153d0 43 75 72 73 6f 72 4b 65 79 28 70 54 72 65 65 43  CursorKey(pTreeC
153e0 73 72 2c 20 26 70 43 73 72 2d 3e 65 54 79 70 65  sr, &pCsr->eType
153f0 2c 20 26 70 2c 20 26 6e 29 3b 0a 20 20 20 20 20  , &p, &n);.     
15400 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d       if( rc==LSM
15410 5f 4f 4b 20 29 20 72 63 20 3d 20 73 6f 72 74 65  _OK ) rc = sorte
15420 64 42 6c 6f 62 53 65 74 28 70 45 6e 76 2c 20 26  dBlobSet(pEnv, &
15430 70 43 73 72 2d 3e 6b 65 79 2c 20 70 2c 20 6e 29  pCsr->key, p, n)
15440 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
15450 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 20 72 63 20  rc==LSM_OK ) rc 
15460 3d 20 6c 73 6d 54 72 65 65 43 75 72 73 6f 72 56  = lsmTreeCursorV
15470 61 6c 75 65 28 70 54 72 65 65 43 73 72 2c 20 26  alue(pTreeCsr, &
15480 70 2c 20 26 6e 29 3b 0a 20 20 20 20 20 20 20 20  p, &n);.        
15490 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
154a0 20 29 20 72 63 20 3d 20 73 6f 72 74 65 64 42 6c   ) rc = sortedBl
154b0 6f 62 53 65 74 28 70 45 6e 76 2c 20 26 70 43 73  obSet(pEnv, &pCs
154c0 72 2d 3e 76 61 6c 2c 20 70 2c 20 6e 29 3b 0a 20  r->val, p, n);. 
154d0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
154e0 20 6c 73 6d 54 72 65 65 43 75 72 73 6f 72 52 65   lsmTreeCursorRe
154f0 73 65 74 28 70 54 72 65 65 43 73 72 29 3b 0a 20  set(pTreeCsr);. 
15500 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
15510 20 20 20 20 7d 0a 20 20 20 20 20 20 63 61 73 65      }.      case
15520 20 4c 53 4d 5f 53 45 45 4b 5f 47 45 3a 0a 20 20   LSM_SEEK_GE:.  
15530 20 20 20 20 20 20 69 66 28 20 72 65 73 3c 30 20        if( res<0 
15540 26 26 20 6c 73 6d 54 72 65 65 43 75 72 73 6f 72  && lsmTreeCursor
15550 56 61 6c 69 64 28 70 54 72 65 65 43 73 72 29 20  Valid(pTreeCsr) 
15560 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6c 73 6d  ){.          lsm
15570 54 72 65 65 43 75 72 73 6f 72 4e 65 78 74 28 70  TreeCursorNext(p
15580 54 72 65 65 43 73 72 29 3b 0a 20 20 20 20 20 20  TreeCsr);.      
15590 20 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61    }.        brea
155a0 6b 3b 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74  k;.      default
155b0 3a 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 65  :.        if( re
155c0 73 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  s>0 ){.         
155d0 20 61 73 73 65 72 74 28 20 6c 73 6d 54 72 65 65   assert( lsmTree
155e0 43 75 72 73 6f 72 56 61 6c 69 64 28 70 54 72 65  CursorValid(pTre
155f0 65 43 73 72 29 20 29 3b 0a 20 20 20 20 20 20 20  eCsr) );.       
15600 20 20 20 6c 73 6d 54 72 65 65 43 75 72 73 6f 72     lsmTreeCursor
15610 50 72 65 76 28 70 54 72 65 65 43 73 72 29 3b 0a  Prev(pTreeCsr);.
15620 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
15630 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20    break;.    }. 
15640 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
15650 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 53 65 65 6b 20 74  }.../*.** Seek t
15660 68 65 20 63 75 72 73 6f 72 2e 0a 2a 2f 0a 69 6e  he cursor..*/.in
15670 74 20 6c 73 6d 4d 43 75 72 73 6f 72 53 65 65 6b  t lsmMCursorSeek
15680 28 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  (.  MultiCursor 
15690 2a 70 43 73 72 2c 20 0a 20 20 69 6e 74 20 69 54  *pCsr, .  int iT
156a0 6f 70 69 63 2c 20 0a 20 20 76 6f 69 64 20 2a 70  opic, .  void *p
156b0 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79 2c 20 0a  Key, int nKey, .
156c0 20 20 69 6e 74 20 65 53 65 65 6b 0a 29 7b 0a 20    int eSeek.){. 
156d0 20 69 6e 74 20 65 45 53 65 65 6b 20 3d 20 65 53   int eESeek = eS
156e0 65 65 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  eek;            
156f0 20 2f 2a 20 45 66 66 65 63 74 69 76 65 20 65 53   /* Effective eS
15700 65 65 6b 20 70 61 72 61 6d 65 74 65 72 20 2a 2f  eek parameter */
15710 0a 20 20 69 6e 74 20 62 53 74 6f 70 20 3d 20 30  .  int bStop = 0
15720 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
15730 20 20 20 2f 2a 20 53 65 74 20 74 6f 20 74 72 75     /* Set to tru
15740 65 20 74 6f 20 68 61 6c 74 20 73 65 61 72 63 68  e to halt search
15750 20 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 20 20   operation */.  
15760 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b  int rc = LSM_OK;
15770 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15780 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
15790 2f 0a 20 20 69 6e 74 20 69 50 74 72 20 3d 20 30  /.  int iPtr = 0
157a0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
157b0 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69      /* Used to i
157c0 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 70  terate through p
157d0 43 73 72 2d 3e 61 50 74 72 5b 5d 20 2a 2f 0a 20  Csr->aPtr[] */. 
157e0 20 4c 73 6d 50 67 6e 6f 20 69 50 67 6e 6f 20 3d   LsmPgno iPgno =
157f0 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
15800 20 2f 2a 20 46 43 20 70 6f 69 6e 74 65 72 20 76   /* FC pointer v
15810 61 6c 75 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72  alue */..  asser
15820 74 28 20 70 43 73 72 2d 3e 61 70 54 72 65 65 43  t( pCsr->apTreeC
15830 73 72 5b 30 5d 3d 3d 30 20 7c 7c 20 69 54 6f 70  sr[0]==0 || iTop
15840 69 63 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  ic==0 );.  asser
15850 74 28 20 70 43 73 72 2d 3e 61 70 54 72 65 65 43  t( pCsr->apTreeC
15860 73 72 5b 31 5d 3d 3d 30 20 7c 7c 20 69 54 6f 70  sr[1]==0 || iTop
15870 69 63 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20  ic==0 );..  if( 
15880 65 45 53 65 65 6b 3d 3d 4c 53 4d 5f 53 45 45 4b  eESeek==LSM_SEEK
15890 5f 4c 45 46 41 53 54 20 29 20 65 45 53 65 65 6b  _LEFAST ) eESeek
158a0 20 3d 20 4c 53 4d 5f 53 45 45 4b 5f 4c 45 3b 0a   = LSM_SEEK_LE;.
158b0 0a 20 20 61 73 73 65 72 74 28 20 65 45 53 65 65  .  assert( eESee
158c0 6b 3d 3d 4c 53 4d 5f 53 45 45 4b 5f 45 51 20 7c  k==LSM_SEEK_EQ |
158d0 7c 20 65 45 53 65 65 6b 3d 3d 4c 53 4d 5f 53 45  | eESeek==LSM_SE
158e0 45 4b 5f 4c 45 20 7c 7c 20 65 45 53 65 65 6b 3d  EK_LE || eESeek=
158f0 3d 4c 53 4d 5f 53 45 45 4b 5f 47 45 20 29 3b 0a  =LSM_SEEK_GE );.
15900 20 20 61 73 73 65 72 74 28 20 28 70 43 73 72 2d    assert( (pCsr-
15910 3e 66 6c 61 67 73 20 26 20 43 55 52 53 4f 52 5f  >flags & CURSOR_
15920 46 4c 55 53 48 5f 46 52 45 45 4c 49 53 54 29 3d  FLUSH_FREELIST)=
15930 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
15940 70 43 73 72 2d 3e 6e 50 74 72 3d 3d 30 20 7c 7c  pCsr->nPtr==0 ||
15950 20 70 43 73 72 2d 3e 61 50 74 72 5b 30 5d 2e 70   pCsr->aPtr[0].p
15960 4c 65 76 65 6c 20 29 3b 0a 0a 20 20 70 43 73 72  Level );..  pCsr
15970 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 28 43 55 52  ->flags &= ~(CUR
15980 53 4f 52 5f 4e 45 58 54 5f 4f 4b 20 7c 20 43 55  SOR_NEXT_OK | CU
15990 52 53 4f 52 5f 50 52 45 56 5f 4f 4b 20 7c 20 43  RSOR_PREV_OK | C
159a0 55 52 53 4f 52 5f 53 45 45 4b 5f 45 51 29 3b 0a  URSOR_SEEK_EQ);.
159b0 20 20 72 63 20 3d 20 74 72 65 65 43 75 72 73 6f    rc = treeCurso
159c0 72 53 65 65 6b 28 70 43 73 72 2c 20 70 43 73 72  rSeek(pCsr, pCsr
159d0 2d 3e 61 70 54 72 65 65 43 73 72 5b 30 5d 2c 20  ->apTreeCsr[0], 
159e0 70 4b 65 79 2c 20 6e 4b 65 79 2c 20 65 45 53 65  pKey, nKey, eESe
159f0 65 6b 2c 20 26 62 53 74 6f 70 29 3b 0a 20 20 69  ek, &bStop);.  i
15a00 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26  f( rc==LSM_OK &&
15a10 20 62 53 74 6f 70 3d 3d 30 20 29 7b 0a 20 20 20   bStop==0 ){.   
15a20 20 72 63 20 3d 20 74 72 65 65 43 75 72 73 6f 72   rc = treeCursor
15a30 53 65 65 6b 28 70 43 73 72 2c 20 70 43 73 72 2d  Seek(pCsr, pCsr-
15a40 3e 61 70 54 72 65 65 43 73 72 5b 31 5d 2c 20 70  >apTreeCsr[1], p
15a50 4b 65 79 2c 20 6e 4b 65 79 2c 20 65 45 53 65 65  Key, nKey, eESee
15a60 6b 2c 20 26 62 53 74 6f 70 29 3b 0a 20 20 7d 0a  k, &bStop);.  }.
15a70 0a 20 20 2f 2a 20 53 65 65 6b 20 61 6c 6c 20 73  .  /* Seek all s
15a80 65 67 6d 65 6e 74 20 70 6f 69 6e 74 65 72 73 2e  egment pointers.
15a90 20 2a 2f 0a 20 20 66 6f 72 28 69 50 74 72 3d 30   */.  for(iPtr=0
15aa0 3b 20 69 50 74 72 3c 70 43 73 72 2d 3e 6e 50 74  ; iPtr<pCsr->nPt
15ab0 72 20 26 26 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20  r && rc==LSM_OK 
15ac0 26 26 20 62 53 74 6f 70 3d 3d 30 3b 20 69 50 74  && bStop==0; iPt
15ad0 72 2b 2b 29 7b 0a 20 20 20 20 53 65 67 6d 65 6e  r++){.    Segmen
15ae0 74 50 74 72 20 2a 70 50 74 72 20 3d 20 26 70 43  tPtr *pPtr = &pC
15af0 73 72 2d 3e 61 50 74 72 5b 69 50 74 72 5d 3b 0a  sr->aPtr[iPtr];.
15b00 20 20 20 20 61 73 73 65 72 74 28 20 70 50 74 72      assert( pPtr
15b10 2d 3e 70 53 65 67 3d 3d 26 70 50 74 72 2d 3e 70  ->pSeg==&pPtr->p
15b20 4c 65 76 65 6c 2d 3e 6c 68 73 20 29 3b 0a 20 20  Level->lhs );.  
15b30 20 20 72 63 20 3d 20 73 65 65 6b 49 6e 4c 65 76    rc = seekInLev
15b40 65 6c 28 70 43 73 72 2c 20 70 50 74 72 2c 20 65  el(pCsr, pPtr, e
15b50 45 53 65 65 6b 2c 20 69 54 6f 70 69 63 2c 20 70  ESeek, iTopic, p
15b60 4b 65 79 2c 20 6e 4b 65 79 2c 20 26 69 50 67 6e  Key, nKey, &iPgn
15b70 6f 2c 20 26 62 53 74 6f 70 29 3b 0a 20 20 20 20  o, &bStop);.    
15b80 69 50 74 72 20 2b 3d 20 70 50 74 72 2d 3e 70 4c  iPtr += pPtr->pL
15b90 65 76 65 6c 2d 3e 6e 52 69 67 68 74 3b 0a 20 20  evel->nRight;.  
15ba0 7d 0a 0a 20 20 69 66 28 20 65 53 65 65 6b 21 3d  }..  if( eSeek!=
15bb0 4c 53 4d 5f 53 45 45 4b 5f 45 51 20 29 7b 0a 20  LSM_SEEK_EQ ){. 
15bc0 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
15bd0 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  K ){.      rc = 
15be0 6d 75 6c 74 69 43 75 72 73 6f 72 41 6c 6c 6f 63  multiCursorAlloc
15bf0 54 72 65 65 28 70 43 73 72 29 3b 0a 20 20 20 20  Tree(pCsr);.    
15c00 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53  }.    if( rc==LS
15c10 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 6e  M_OK ){.      in
15c20 74 20 69 3b 0a 20 20 20 20 20 20 66 6f 72 28 69  t i;.      for(i
15c30 3d 70 43 73 72 2d 3e 6e 54 72 65 65 2d 31 3b 20  =pCsr->nTree-1; 
15c40 69 3e 30 3b 20 69 2d 2d 29 7b 0a 20 20 20 20 20  i>0; i--){.     
15c50 20 20 20 6d 75 6c 74 69 43 75 72 73 6f 72 44 6f     multiCursorDo
15c60 43 6f 6d 70 61 72 65 28 70 43 73 72 2c 20 69 2c  Compare(pCsr, i,
15c70 20 65 45 53 65 65 6b 3d 3d 4c 53 4d 5f 53 45 45   eESeek==LSM_SEE
15c80 4b 5f 4c 45 29 3b 0a 20 20 20 20 20 20 7d 0a 20  K_LE);.      }. 
15c90 20 20 20 20 20 69 66 28 20 65 53 65 65 6b 3d 3d       if( eSeek==
15ca0 4c 53 4d 5f 53 45 45 4b 5f 47 45 20 29 20 70 43  LSM_SEEK_GE ) pC
15cb0 73 72 2d 3e 66 6c 61 67 73 20 7c 3d 20 43 55 52  sr->flags |= CUR
15cc0 53 4f 52 5f 4e 45 58 54 5f 4f 4b 3b 0a 20 20 20  SOR_NEXT_OK;.   
15cd0 20 20 20 69 66 28 20 65 53 65 65 6b 3d 3d 4c 53     if( eSeek==LS
15ce0 4d 5f 53 45 45 4b 5f 4c 45 20 29 20 70 43 73 72  M_SEEK_LE ) pCsr
15cf0 2d 3e 66 6c 61 67 73 20 7c 3d 20 43 55 52 53 4f  ->flags |= CURSO
15d00 52 5f 50 52 45 56 5f 4f 4b 3b 0a 20 20 20 20 7d  R_PREV_OK;.    }
15d10 0a 0a 20 20 20 20 6d 75 6c 74 69 43 75 72 73 6f  ..    multiCurso
15d20 72 43 61 63 68 65 4b 65 79 28 70 43 73 72 2c 20  rCacheKey(pCsr, 
15d30 26 72 63 29 3b 0a 20 20 20 20 69 66 28 20 72 63  &rc);.    if( rc
15d40 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 65 53 65 65  ==LSM_OK && eSee
15d50 6b 21 3d 4c 53 4d 5f 53 45 45 4b 5f 4c 45 46 41  k!=LSM_SEEK_LEFA
15d60 53 54 20 26 26 20 30 3d 3d 6d 63 75 72 73 6f 72  ST && 0==mcursor
15d70 4c 6f 63 61 74 69 6f 6e 4f 6b 28 70 43 73 72 2c  LocationOk(pCsr,
15d80 20 30 29 20 29 7b 0a 20 20 20 20 20 20 73 77 69   0) ){.      swi
15d90 74 63 68 28 20 65 45 53 65 65 6b 20 29 7b 0a 20  tch( eESeek ){. 
15da0 20 20 20 20 20 20 20 63 61 73 65 20 4c 53 4d 5f         case LSM_
15db0 53 45 45 4b 5f 45 51 3a 0a 20 20 20 20 20 20 20  SEEK_EQ:.       
15dc0 20 20 20 6c 73 6d 4d 43 75 72 73 6f 72 52 65 73     lsmMCursorRes
15dd0 65 74 28 70 43 73 72 29 3b 0a 20 20 20 20 20 20  et(pCsr);.      
15de0 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
15df0 20 20 20 63 61 73 65 20 4c 53 4d 5f 53 45 45 4b     case LSM_SEEK
15e00 5f 47 45 3a 0a 20 20 20 20 20 20 20 20 20 20 72  _GE:.          r
15e10 63 20 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 4e 65  c = lsmMCursorNe
15e20 78 74 28 70 43 73 72 29 3b 0a 20 20 20 20 20 20  xt(pCsr);.      
15e30 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
15e40 20 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20     default:.    
15e50 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 4d 43        rc = lsmMC
15e60 75 72 73 6f 72 50 72 65 76 28 70 43 73 72 29 3b  ursorPrev(pCsr);
15e70 0a 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b  .          break
15e80 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
15e90 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
15ea0 3b 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 4d 43 75 72  ;.}..int lsmMCur
15eb0 73 6f 72 56 61 6c 69 64 28 4d 75 6c 74 69 43 75  sorValid(MultiCu
15ec0 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 69  rsor *pCsr){.  i
15ed0 6e 74 20 72 65 73 20 3d 20 30 3b 0a 20 20 69 66  nt res = 0;.  if
15ee0 28 20 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20  ( pCsr->flags & 
15ef0 43 55 52 53 4f 52 5f 53 45 45 4b 5f 45 51 20 29  CURSOR_SEEK_EQ )
15f00 7b 0a 20 20 20 20 72 65 73 20 3d 20 31 3b 0a 20  {.    res = 1;. 
15f10 20 7d 65 6c 73 65 20 69 66 28 20 70 43 73 72 2d   }else if( pCsr-
15f20 3e 61 54 72 65 65 20 29 7b 0a 20 20 20 20 69 6e  >aTree ){.    in
15f30 74 20 69 4b 65 79 20 3d 20 70 43 73 72 2d 3e 61  t iKey = pCsr->a
15f40 54 72 65 65 5b 31 5d 3b 0a 20 20 20 20 69 66 28  Tree[1];.    if(
15f50 20 69 4b 65 79 3d 3d 43 55 52 53 4f 52 5f 44 41   iKey==CURSOR_DA
15f60 54 41 5f 54 52 45 45 30 20 7c 7c 20 69 4b 65 79  TA_TREE0 || iKey
15f70 3d 3d 43 55 52 53 4f 52 5f 44 41 54 41 5f 54 52  ==CURSOR_DATA_TR
15f80 45 45 31 20 29 7b 0a 20 20 20 20 20 20 72 65 73  EE1 ){.      res
15f90 20 3d 20 6c 73 6d 54 72 65 65 43 75 72 73 6f 72   = lsmTreeCursor
15fa0 56 61 6c 69 64 28 70 43 73 72 2d 3e 61 70 54 72  Valid(pCsr->apTr
15fb0 65 65 43 73 72 5b 69 4b 65 79 2d 43 55 52 53 4f  eeCsr[iKey-CURSO
15fc0 52 5f 44 41 54 41 5f 54 52 45 45 30 5d 29 3b 0a  R_DATA_TREE0]);.
15fd0 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
15fe0 20 76 6f 69 64 20 2a 70 4b 65 79 3b 20 0a 20 20   void *pKey; .  
15ff0 20 20 20 20 6d 75 6c 74 69 43 75 72 73 6f 72 47      multiCursorG
16000 65 74 4b 65 79 28 70 43 73 72 2c 20 69 4b 65 79  etKey(pCsr, iKey
16010 2c 20 30 2c 20 26 70 4b 65 79 2c 20 30 29 3b 0a  , 0, &pKey, 0);.
16020 20 20 20 20 20 20 72 65 73 20 3d 20 70 4b 65 79        res = pKey
16030 21 3d 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  !=0;.    }.  }. 
16040 20 72 65 74 75 72 6e 20 72 65 73 3b 0a 7d 0a 0a   return res;.}..
16050 73 74 61 74 69 63 20 69 6e 74 20 6d 63 75 72 73  static int mcurs
16060 6f 72 41 64 76 61 6e 63 65 4f 6b 28 0a 20 20 4d  orAdvanceOk(.  M
16070 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72  ultiCursor *pCsr
16080 2c 20 0a 20 20 69 6e 74 20 62 52 65 76 65 72 73  , .  int bRevers
16090 65 2c 0a 20 20 69 6e 74 20 2a 70 52 63 0a 29 7b  e,.  int *pRc.){
160a0 0a 20 20 76 6f 69 64 20 2a 70 4e 65 77 3b 20 20  .  void *pNew;  
160b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
160c0 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
160d0 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69   buffer containi
160e0 6e 67 20 6e 65 77 20 6b 65 79 20 2a 2f 0a 20 20  ng new key */.  
160f0 69 6e 74 20 6e 4e 65 77 3b 20 20 20 20 20 20 20  int nNew;       
16100 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16110 2f 2a 20 53 69 7a 65 20 6f 66 20 62 75 66 66 65  /* Size of buffe
16120 72 20 70 4e 65 77 20 69 6e 20 62 79 74 65 73 20  r pNew in bytes 
16130 2a 2f 0a 20 20 69 6e 74 20 65 4e 65 77 54 79 70  */.  int eNewTyp
16140 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
16150 20 20 20 20 20 2f 2a 20 54 79 70 65 20 6f 66 20       /* Type of 
16160 6e 65 77 20 72 65 63 6f 72 64 20 2a 2f 0a 0a 20  new record */.. 
16170 20 69 66 28 20 2a 70 52 63 20 29 20 72 65 74 75   if( *pRc ) retu
16180 72 6e 20 31 3b 0a 0a 20 20 2f 2a 20 43 68 65 63  rn 1;..  /* Chec
16190 6b 20 74 68 65 20 63 75 72 72 65 6e 74 20 6b 65  k the current ke
161a0 79 20 76 61 6c 75 65 2e 20 49 66 20 69 74 20 69  y value. If it i
161b0 73 20 6e 6f 74 20 67 72 65 61 74 65 72 20 74 68  s not greater th
161c0 61 6e 20 28 69 66 20 62 52 65 76 65 72 73 65 3d  an (if bReverse=
161d0 3d 30 29 0a 20 20 2a 2a 20 6f 72 20 6c 65 73 73  =0).  ** or less
161e0 20 74 68 61 6e 20 28 69 66 20 62 52 65 76 65 72   than (if bRever
161f0 73 65 21 3d 30 29 20 74 68 65 20 6b 65 79 20 63  se!=0) the key c
16200 75 72 72 65 6e 74 6c 79 20 63 61 63 68 65 64 20  urrently cached 
16210 69 6e 20 70 43 73 72 2d 3e 6b 65 79 2c 20 0a 20  in pCsr->key, . 
16220 20 2a 2a 20 74 68 65 6e 20 74 68 65 20 63 75 72   ** then the cur
16230 73 6f 72 20 68 61 73 20 6e 6f 74 20 79 65 74 20  sor has not yet 
16240 62 65 65 6e 20 73 75 63 63 65 73 73 66 75 6c 6c  been successfull
16250 79 20 61 64 76 61 6e 63 65 64 2e 20 20 0a 20 20  y advanced.  .  
16260 2a 2f 0a 20 20 6d 75 6c 74 69 43 75 72 73 6f 72  */.  multiCursor
16270 47 65 74 4b 65 79 28 70 43 73 72 2c 20 70 43 73  GetKey(pCsr, pCs
16280 72 2d 3e 61 54 72 65 65 5b 31 5d 2c 20 26 65 4e  r->aTree[1], &eN
16290 65 77 54 79 70 65 2c 20 26 70 4e 65 77 2c 20 26  ewType, &pNew, &
162a0 6e 4e 65 77 29 3b 0a 20 20 69 66 28 20 70 4e 65  nNew);.  if( pNe
162b0 77 20 29 7b 0a 20 20 20 20 69 6e 74 20 74 79 70  w ){.    int typ
162c0 65 6d 61 73 6b 20 3d 20 28 70 43 73 72 2d 3e 66  emask = (pCsr->f
162d0 6c 61 67 73 20 26 20 43 55 52 53 4f 52 5f 49 47  lags & CURSOR_IG
162e0 4e 4f 52 45 5f 44 45 4c 45 54 45 29 20 3f 20 7e  NORE_DELETE) ? ~
162f0 28 30 29 20 3a 20 4c 53 4d 5f 53 59 53 54 45 4d  (0) : LSM_SYSTEM
16300 4b 45 59 3b 0a 20 20 20 20 69 6e 74 20 72 65 73  KEY;.    int res
16310 20 3d 20 73 6f 72 74 65 64 44 62 4b 65 79 43 6f   = sortedDbKeyCo
16320 6d 70 61 72 65 28 70 43 73 72 2c 0a 20 20 20 20  mpare(pCsr,.    
16330 20 20 65 4e 65 77 54 79 70 65 20 26 20 74 79 70    eNewType & typ
16340 65 6d 61 73 6b 2c 20 70 4e 65 77 2c 20 6e 4e 65  emask, pNew, nNe
16350 77 2c 20 0a 20 20 20 20 20 20 70 43 73 72 2d 3e  w, .      pCsr->
16360 65 54 79 70 65 20 26 20 74 79 70 65 6d 61 73 6b  eType & typemask
16370 2c 20 70 43 73 72 2d 3e 6b 65 79 2e 70 44 61 74  , pCsr->key.pDat
16380 61 2c 20 70 43 73 72 2d 3e 6b 65 79 2e 6e 44 61  a, pCsr->key.nDa
16390 74 61 0a 20 20 20 20 29 3b 0a 0a 20 20 20 20 69  ta.    );..    i
163a0 66 28 20 28 62 52 65 76 65 72 73 65 3d 3d 30 20  f( (bReverse==0 
163b0 26 26 20 72 65 73 3c 3d 30 29 20 7c 7c 20 28 62  && res<=0) || (b
163c0 52 65 76 65 72 73 65 21 3d 30 20 26 26 20 72 65  Reverse!=0 && re
163d0 73 3e 3d 30 29 20 29 7b 0a 20 20 20 20 20 20 72  s>=0) ){.      r
163e0 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 0a  eturn 0;.    }..
163f0 20 20 20 20 6d 75 6c 74 69 43 75 72 73 6f 72 43      multiCursorC
16400 61 63 68 65 4b 65 79 28 70 43 73 72 2c 20 70 52  acheKey(pCsr, pR
16410 63 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  c);.    assert( 
16420 70 43 73 72 2d 3e 65 54 79 70 65 3d 3d 65 4e 65  pCsr->eType==eNe
16430 77 54 79 70 65 20 29 3b 0a 0a 20 20 20 20 2f 2a  wType );..    /*
16440 20 49 66 20 74 68 69 73 20 63 75 72 73 6f 72 20   If this cursor 
16450 69 73 20 63 6f 6e 66 69 67 75 72 65 64 20 74 6f  is configured to
16460 20 73 6b 69 70 20 64 65 6c 65 74 65 64 20 6b 65   skip deleted ke
16470 79 73 2c 20 61 6e 64 20 74 68 65 20 63 75 72 72  ys, and the curr
16480 65 6e 74 0a 20 20 20 20 2a 2a 20 63 75 72 73 6f  ent.    ** curso
16490 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 53 4f  r points to a SO
164a0 52 54 45 44 5f 44 45 4c 45 54 45 20 65 6e 74 72  RTED_DELETE entr
164b0 79 2c 20 74 68 65 6e 20 74 68 65 20 63 75 72 73  y, then the curs
164c0 6f 72 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20  or has not been 
164d0 0a 20 20 20 20 2a 2a 20 73 75 63 63 65 73 73 66  .    ** successf
164e0 75 6c 6c 79 20 61 64 76 61 6e 63 65 64 2e 20 20  ully advanced.  
164f0 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 53  .    **.    ** S
16500 69 6d 69 6c 61 72 6c 79 2c 20 69 66 20 74 68 65  imilarly, if the
16510 20 63 75 72 73 6f 72 20 69 73 20 63 6f 6e 66 69   cursor is confi
16520 67 75 72 65 64 20 74 6f 20 73 6b 69 70 20 73 79  gured to skip sy
16530 73 74 65 6d 20 6b 65 79 73 20 61 6e 64 20 74 68  stem keys and th
16540 65 0a 20 20 20 20 2a 2a 20 63 75 72 72 65 6e 74  e.    ** current
16550 20 63 75 72 73 6f 72 20 70 6f 69 6e 74 73 20 74   cursor points t
16560 6f 20 61 20 73 79 73 74 65 6d 20 6b 65 79 2c 20  o a system key, 
16570 69 74 20 68 61 73 20 6e 6f 74 20 79 65 74 20 62  it has not yet b
16580 65 65 6e 20 61 64 76 61 6e 63 65 64 2e 0a 20 20  een advanced..  
16590 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 2a 70 52    */.    if( *pR
165a0 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 30 3d 3d  c==LSM_OK && 0==
165b0 6d 63 75 72 73 6f 72 4c 6f 63 61 74 69 6f 6e 4f  mcursorLocationO
165c0 6b 28 70 43 73 72 2c 20 30 29 20 29 20 72 65 74  k(pCsr, 0) ) ret
165d0 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74  urn 0;.  }.  ret
165e0 75 72 6e 20 31 3b 0a 7d 0a 0a 73 74 61 74 69 63  urn 1;.}..static
165f0 20 76 6f 69 64 20 66 6c 43 73 72 41 64 76 61 6e   void flCsrAdvan
16600 63 65 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a  ce(MultiCursor *
16610 70 43 73 72 29 7b 0a 20 20 61 73 73 65 72 74 28  pCsr){.  assert(
16620 20 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20 43   pCsr->flags & C
16630 55 52 53 4f 52 5f 46 4c 55 53 48 5f 46 52 45 45  URSOR_FLUSH_FREE
16640 4c 49 53 54 20 29 3b 0a 20 20 69 66 28 20 70 43  LIST );.  if( pC
16650 73 72 2d 3e 69 46 72 65 65 20 25 20 32 20 29 7b  sr->iFree % 2 ){
16660 0a 20 20 20 20 70 43 73 72 2d 3e 69 46 72 65 65  .    pCsr->iFree
16670 2b 2b 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ++;.  }else{.   
16680 20 69 6e 74 20 6e 45 6e 74 72 79 20 3d 20 70 43   int nEntry = pC
16690 73 72 2d 3e 70 44 62 2d 3e 70 57 6f 72 6b 65 72  sr->pDb->pWorker
166a0 2d 3e 66 72 65 65 6c 69 73 74 2e 6e 45 6e 74 72  ->freelist.nEntr
166b0 79 3b 0a 20 20 20 20 46 72 65 65 6c 69 73 74 45  y;.    FreelistE
166c0 6e 74 72 79 20 2a 61 45 6e 74 72 79 20 3d 20 70  ntry *aEntry = p
166d0 43 73 72 2d 3e 70 44 62 2d 3e 70 57 6f 72 6b 65  Csr->pDb->pWorke
166e0 72 2d 3e 66 72 65 65 6c 69 73 74 2e 61 45 6e 74  r->freelist.aEnt
166f0 72 79 3b 0a 0a 20 20 20 20 69 6e 74 20 69 20 3d  ry;..    int i =
16700 20 6e 45 6e 74 72 79 20 2d 20 31 20 2d 20 28 70   nEntry - 1 - (p
16710 43 73 72 2d 3e 69 46 72 65 65 20 2f 20 32 29 3b  Csr->iFree / 2);
16720 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20  ..    /* If the 
16730 63 75 72 72 65 6e 74 20 65 6e 74 72 79 20 69 73  current entry is
16740 20 61 20 64 65 6c 65 74 65 20 61 6e 64 20 74 68   a delete and th
16750 65 20 22 65 6e 64 2d 64 65 6c 65 74 65 22 20 6b  e "end-delete" k
16760 65 79 20 77 69 6c 6c 20 6e 6f 74 0a 20 20 20 20  ey will not.    
16770 2a 2a 20 62 65 20 61 74 74 61 63 68 65 64 20 74  ** be attached t
16780 6f 20 74 68 65 20 6e 65 78 74 20 65 6e 74 72 79  o the next entry
16790 2c 20 69 6e 63 72 65 6d 65 6e 74 20 69 46 72 65  , increment iFre
167a0 65 20 62 79 20 31 20 6f 6e 6c 79 2e 20 2a 2f 0a  e by 1 only. */.
167b0 20 20 20 20 69 66 28 20 61 45 6e 74 72 79 5b 69      if( aEntry[i
167c0 5d 2e 69 49 64 3c 30 20 29 7b 0a 20 20 20 20 20  ].iId<0 ){.     
167d0 20 77 68 69 6c 65 28 20 31 20 29 7b 0a 20 20 20   while( 1 ){.   
167e0 20 20 20 20 20 69 66 28 20 69 3d 3d 30 20 7c 7c       if( i==0 ||
167f0 20 61 45 6e 74 72 79 5b 69 2d 31 5d 2e 69 42 6c   aEntry[i-1].iBl
16800 6b 21 3d 61 45 6e 74 72 79 5b 69 5d 2e 69 42 6c  k!=aEntry[i].iBl
16810 6b 2d 31 20 29 7b 0a 20 20 20 20 20 20 20 20 20  k-1 ){.         
16820 20 70 43 73 72 2d 3e 69 46 72 65 65 2d 2d 3b 0a   pCsr->iFree--;.
16830 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
16840 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
16850 20 20 20 69 66 28 20 61 45 6e 74 72 79 5b 69 2d     if( aEntry[i-
16860 31 5d 2e 69 49 64 3e 3d 30 20 29 20 62 72 65 61  1].iId>=0 ) brea
16870 6b 3b 0a 20 20 20 20 20 20 20 20 70 43 73 72 2d  k;.        pCsr-
16880 3e 69 46 72 65 65 20 2b 3d 20 32 3b 0a 20 20 20  >iFree += 2;.   
16890 20 20 20 20 20 69 2d 2d 3b 0a 20 20 20 20 20 20       i--;.      
168a0 7d 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 73 72  }.    }.    pCsr
168b0 2d 3e 69 46 72 65 65 20 2b 3d 20 32 3b 0a 20 20  ->iFree += 2;.  
168c0 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  }.}..static int 
168d0 6d 75 6c 74 69 43 75 72 73 6f 72 41 64 76 61 6e  multiCursorAdvan
168e0 63 65 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a  ce(MultiCursor *
168f0 70 43 73 72 2c 20 69 6e 74 20 62 52 65 76 65 72  pCsr, int bRever
16900 73 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  se){.  int rc = 
16910 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  LSM_OK;         
16920 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
16930 20 43 6f 64 65 20 2a 2f 0a 20 20 69 66 28 20 6c   Code */.  if( l
16940 73 6d 4d 43 75 72 73 6f 72 56 61 6c 69 64 28 70  smMCursorValid(p
16950 43 73 72 29 20 29 7b 0a 20 20 20 20 64 6f 20 7b  Csr) ){.    do {
16960 0a 20 20 20 20 20 20 69 6e 74 20 69 4b 65 79 20  .      int iKey 
16970 3d 20 70 43 73 72 2d 3e 61 54 72 65 65 5b 31 5d  = pCsr->aTree[1]
16980 3b 0a 0a 20 20 20 20 20 20 61 73 73 65 72 74 43  ;..      assertC
16990 75 72 73 6f 72 54 72 65 65 28 70 43 73 72 29 3b  ursorTree(pCsr);
169a0 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68  ..      /* If th
169b0 69 73 20 6d 75 6c 74 69 2d 63 75 72 73 6f 72 20  is multi-cursor 
169c0 69 73 20 61 64 76 61 6e 63 69 6e 67 20 66 6f 72  is advancing for
169d0 77 61 72 64 73 2c 20 61 6e 64 20 74 68 65 20 73  wards, and the s
169e0 75 62 2d 63 75 72 73 6f 72 0a 20 20 20 20 20 20  ub-cursor.      
169f0 2a 2a 20 62 65 69 6e 67 20 61 64 76 61 6e 63 65  ** being advance
16a00 64 20 69 73 20 74 68 65 20 6f 6e 65 20 74 68 61  d is the one tha
16a10 74 20 73 65 70 61 72 61 74 6f 72 20 6b 65 79 73  t separator keys
16a20 20 6d 61 79 20 62 65 20 62 65 69 6e 67 20 72 65   may be being re
16a30 61 64 0a 20 20 20 20 20 20 2a 2a 20 66 72 6f 6d  ad.      ** from
16a40 2c 20 72 65 63 6f 72 64 20 74 68 65 20 63 75 72  , record the cur
16a50 72 65 6e 74 20 61 62 73 6f 6c 75 74 65 20 70 6f  rent absolute po
16a60 69 6e 74 65 72 20 76 61 6c 75 65 2e 20 20 2a 2f  inter value.  */
16a70 0a 20 20 20 20 20 20 69 66 28 20 70 43 73 72 2d  .      if( pCsr-
16a80 3e 70 50 72 65 76 4d 65 72 67 65 50 74 72 20 29  >pPrevMergePtr )
16a90 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 4b  {.        if( iK
16aa0 65 79 3d 3d 28 43 55 52 53 4f 52 5f 44 41 54 41  ey==(CURSOR_DATA
16ab0 5f 53 45 47 4d 45 4e 54 2b 70 43 73 72 2d 3e 6e  _SEGMENT+pCsr->n
16ac0 50 74 72 29 20 29 7b 0a 20 20 20 20 20 20 20 20  Ptr) ){.        
16ad0 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
16ae0 70 42 74 43 73 72 20 29 3b 0a 20 20 20 20 20 20  pBtCsr );.      
16af0 20 20 20 20 2a 70 43 73 72 2d 3e 70 50 72 65 76      *pCsr->pPrev
16b00 4d 65 72 67 65 50 74 72 20 3d 20 70 43 73 72 2d  MergePtr = pCsr-
16b10 3e 70 42 74 43 73 72 2d 3e 69 50 74 72 3b 0a 20  >pBtCsr->iPtr;. 
16b20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28         }else if(
16b30 20 70 43 73 72 2d 3e 70 42 74 43 73 72 3d 3d 30   pCsr->pBtCsr==0
16b40 20 26 26 20 70 43 73 72 2d 3e 6e 50 74 72 3e 30   && pCsr->nPtr>0
16b50 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
16b60 26 26 20 69 4b 65 79 3d 3d 28 43 55 52 53 4f 52  && iKey==(CURSOR
16b70 5f 44 41 54 41 5f 53 45 47 4d 45 4e 54 2b 70 43  _DATA_SEGMENT+pC
16b80 73 72 2d 3e 6e 50 74 72 2d 31 29 20 0a 20 20 20  sr->nPtr-1) .   
16b90 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20       ){.        
16ba0 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50    SegmentPtr *pP
16bb0 74 72 20 3d 20 26 70 43 73 72 2d 3e 61 50 74 72  tr = &pCsr->aPtr
16bc0 5b 69 4b 65 79 2d 43 55 52 53 4f 52 5f 44 41 54  [iKey-CURSOR_DAT
16bd0 41 5f 53 45 47 4d 45 4e 54 5d 3b 0a 20 20 20 20  A_SEGMENT];.    
16be0 20 20 20 20 20 20 2a 70 43 73 72 2d 3e 70 50 72        *pCsr->pPr
16bf0 65 76 4d 65 72 67 65 50 74 72 20 3d 20 70 50 74  evMergePtr = pPt
16c00 72 2d 3e 69 50 74 72 2b 70 50 74 72 2d 3e 69 50  r->iPtr+pPtr->iP
16c10 67 50 74 72 3b 0a 20 20 20 20 20 20 20 20 7d 0a  gPtr;.        }.
16c20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 69        }..      i
16c30 66 28 20 69 4b 65 79 3d 3d 43 55 52 53 4f 52 5f  f( iKey==CURSOR_
16c40 44 41 54 41 5f 54 52 45 45 30 20 7c 7c 20 69 4b  DATA_TREE0 || iK
16c50 65 79 3d 3d 43 55 52 53 4f 52 5f 44 41 54 41 5f  ey==CURSOR_DATA_
16c60 54 52 45 45 31 20 29 7b 0a 20 20 20 20 20 20 20  TREE1 ){.       
16c70 20 54 72 65 65 43 75 72 73 6f 72 20 2a 70 54 72   TreeCursor *pTr
16c80 65 65 43 73 72 20 3d 20 70 43 73 72 2d 3e 61 70  eeCsr = pCsr->ap
16c90 54 72 65 65 43 73 72 5b 69 4b 65 79 2d 43 55 52  TreeCsr[iKey-CUR
16ca0 53 4f 52 5f 44 41 54 41 5f 54 52 45 45 30 5d 3b  SOR_DATA_TREE0];
16cb0 0a 20 20 20 20 20 20 20 20 69 66 28 20 62 52 65  .        if( bRe
16cc0 76 65 72 73 65 20 29 7b 0a 20 20 20 20 20 20 20  verse ){.       
16cd0 20 20 20 72 63 20 3d 20 6c 73 6d 54 72 65 65 43     rc = lsmTreeC
16ce0 75 72 73 6f 72 50 72 65 76 28 70 54 72 65 65 43  ursorPrev(pTreeC
16cf0 73 72 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  sr);.        }el
16d00 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63  se{.          rc
16d10 20 3d 20 6c 73 6d 54 72 65 65 43 75 72 73 6f 72   = lsmTreeCursor
16d20 4e 65 78 74 28 70 54 72 65 65 43 73 72 29 3b 0a  Next(pTreeCsr);.
16d30 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
16d40 7d 65 6c 73 65 20 69 66 28 20 69 4b 65 79 3d 3d  }else if( iKey==
16d50 43 55 52 53 4f 52 5f 44 41 54 41 5f 53 59 53 54  CURSOR_DATA_SYST
16d60 45 4d 20 29 7b 0a 20 20 20 20 20 20 20 20 61 73  EM ){.        as
16d70 73 65 72 74 28 20 70 43 73 72 2d 3e 66 6c 61 67  sert( pCsr->flag
16d80 73 20 26 20 43 55 52 53 4f 52 5f 46 4c 55 53 48  s & CURSOR_FLUSH
16d90 5f 46 52 45 45 4c 49 53 54 20 29 3b 0a 20 20 20  _FREELIST );.   
16da0 20 20 20 20 20 61 73 73 65 72 74 28 20 62 52 65       assert( bRe
16db0 76 65 72 73 65 3d 3d 30 20 29 3b 0a 20 20 20 20  verse==0 );.    
16dc0 20 20 20 20 66 6c 43 73 72 41 64 76 61 6e 63 65      flCsrAdvance
16dd0 28 70 43 73 72 29 3b 0a 20 20 20 20 20 20 7d 65  (pCsr);.      }e
16de0 6c 73 65 20 69 66 28 20 69 4b 65 79 3d 3d 28 43  lse if( iKey==(C
16df0 55 52 53 4f 52 5f 44 41 54 41 5f 53 45 47 4d 45  URSOR_DATA_SEGME
16e00 4e 54 2b 70 43 73 72 2d 3e 6e 50 74 72 29 20 29  NT+pCsr->nPtr) )
16e10 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  {.        assert
16e20 28 20 62 52 65 76 65 72 73 65 3d 3d 30 20 26 26  ( bReverse==0 &&
16e30 20 70 43 73 72 2d 3e 70 42 74 43 73 72 20 29 3b   pCsr->pBtCsr );
16e40 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 62 74  .        rc = bt
16e50 72 65 65 43 75 72 73 6f 72 4e 65 78 74 28 70 43  reeCursorNext(pC
16e60 73 72 2d 3e 70 42 74 43 73 72 29 3b 0a 20 20 20  sr->pBtCsr);.   
16e70 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
16e80 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 43 75    rc = segmentCu
16e90 72 73 6f 72 41 64 76 61 6e 63 65 28 70 43 73 72  rsorAdvance(pCsr
16ea0 2c 20 69 4b 65 79 2d 43 55 52 53 4f 52 5f 44 41  , iKey-CURSOR_DA
16eb0 54 41 5f 53 45 47 4d 45 4e 54 2c 20 62 52 65 76  TA_SEGMENT, bRev
16ec0 65 72 73 65 29 3b 0a 20 20 20 20 20 20 7d 0a 20  erse);.      }. 
16ed0 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d       if( rc==LSM
16ee0 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69  _OK ){.        i
16ef0 6e 74 20 69 3b 0a 20 20 20 20 20 20 20 20 66 6f  nt i;.        fo
16f00 72 28 69 3d 28 69 4b 65 79 2b 70 43 73 72 2d 3e  r(i=(iKey+pCsr->
16f10 6e 54 72 65 65 29 2f 32 3b 20 69 3e 30 3b 20 69  nTree)/2; i>0; i
16f20 3d 69 2f 32 29 7b 0a 20 20 20 20 20 20 20 20 20  =i/2){.         
16f30 20 6d 75 6c 74 69 43 75 72 73 6f 72 44 6f 43 6f   multiCursorDoCo
16f40 6d 70 61 72 65 28 70 43 73 72 2c 20 69 2c 20 62  mpare(pCsr, i, b
16f50 52 65 76 65 72 73 65 29 3b 0a 20 20 20 20 20 20  Reverse);.      
16f60 20 20 7d 0a 20 20 20 20 20 20 20 20 61 73 73 65    }.        asse
16f70 72 74 43 75 72 73 6f 72 54 72 65 65 28 70 43 73  rtCursorTree(pCs
16f80 72 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  r);.      }.    
16f90 7d 77 68 69 6c 65 28 20 6d 63 75 72 73 6f 72 41  }while( mcursorA
16fa0 64 76 61 6e 63 65 4f 6b 28 70 43 73 72 2c 20 62  dvanceOk(pCsr, b
16fb0 52 65 76 65 72 73 65 2c 20 26 72 63 29 3d 3d 30  Reverse, &rc)==0
16fc0 20 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   );.  }.  return
16fd0 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 4d   rc;.}..int lsmM
16fe0 43 75 72 73 6f 72 4e 65 78 74 28 4d 75 6c 74 69  CursorNext(Multi
16ff0 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20  Cursor *pCsr){. 
17000 20 69 66 28 20 28 70 43 73 72 2d 3e 66 6c 61 67   if( (pCsr->flag
17010 73 20 26 20 43 55 52 53 4f 52 5f 4e 45 58 54 5f  s & CURSOR_NEXT_
17020 4f 4b 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  OK)==0 ) return 
17030 4c 53 4d 5f 4d 49 53 55 53 45 5f 42 4b 50 54 3b  LSM_MISUSE_BKPT;
17040 0a 20 20 72 65 74 75 72 6e 20 6d 75 6c 74 69 43  .  return multiC
17050 75 72 73 6f 72 41 64 76 61 6e 63 65 28 70 43 73  ursorAdvance(pCs
17060 72 2c 20 30 29 3b 0a 7d 0a 0a 69 6e 74 20 6c 73  r, 0);.}..int ls
17070 6d 4d 43 75 72 73 6f 72 50 72 65 76 28 4d 75 6c  mMCursorPrev(Mul
17080 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b  tiCursor *pCsr){
17090 0a 20 20 69 66 28 20 28 70 43 73 72 2d 3e 66 6c  .  if( (pCsr->fl
170a0 61 67 73 20 26 20 43 55 52 53 4f 52 5f 50 52 45  ags & CURSOR_PRE
170b0 56 5f 4f 4b 29 3d 3d 30 20 29 20 72 65 74 75 72  V_OK)==0 ) retur
170c0 6e 20 4c 53 4d 5f 4d 49 53 55 53 45 5f 42 4b 50  n LSM_MISUSE_BKP
170d0 54 3b 0a 20 20 72 65 74 75 72 6e 20 6d 75 6c 74  T;.  return mult
170e0 69 43 75 72 73 6f 72 41 64 76 61 6e 63 65 28 70  iCursorAdvance(p
170f0 43 73 72 2c 20 31 29 3b 0a 7d 0a 0a 69 6e 74 20  Csr, 1);.}..int 
17100 6c 73 6d 4d 43 75 72 73 6f 72 4b 65 79 28 4d 75  lsmMCursorKey(Mu
17110 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  ltiCursor *pCsr,
17120 20 76 6f 69 64 20 2a 2a 70 70 4b 65 79 2c 20 69   void **ppKey, i
17130 6e 74 20 2a 70 6e 4b 65 79 29 7b 0a 20 20 69 66  nt *pnKey){.  if
17140 28 20 28 70 43 73 72 2d 3e 66 6c 61 67 73 20 26  ( (pCsr->flags &
17150 20 43 55 52 53 4f 52 5f 53 45 45 4b 5f 45 51 29   CURSOR_SEEK_EQ)
17160 20 7c 7c 20 70 43 73 72 2d 3e 61 54 72 65 65 3d   || pCsr->aTree=
17170 3d 30 20 29 7b 0a 20 20 20 20 2a 70 6e 4b 65 79  =0 ){.    *pnKey
17180 20 3d 20 70 43 73 72 2d 3e 6b 65 79 2e 6e 44 61   = pCsr->key.nDa
17190 74 61 3b 0a 20 20 20 20 2a 70 70 4b 65 79 20 3d  ta;.    *ppKey =
171a0 20 70 43 73 72 2d 3e 6b 65 79 2e 70 44 61 74 61   pCsr->key.pData
171b0 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  ;.  }else{.    i
171c0 6e 74 20 69 4b 65 79 20 3d 20 70 43 73 72 2d 3e  nt iKey = pCsr->
171d0 61 54 72 65 65 5b 31 5d 3b 0a 0a 20 20 20 20 69  aTree[1];..    i
171e0 66 28 20 69 4b 65 79 3d 3d 43 55 52 53 4f 52 5f  f( iKey==CURSOR_
171f0 44 41 54 41 5f 54 52 45 45 30 20 7c 7c 20 69 4b  DATA_TREE0 || iK
17200 65 79 3d 3d 43 55 52 53 4f 52 5f 44 41 54 41 5f  ey==CURSOR_DATA_
17210 54 52 45 45 31 20 29 7b 0a 20 20 20 20 20 20 54  TREE1 ){.      T
17220 72 65 65 43 75 72 73 6f 72 20 2a 70 54 72 65 65  reeCursor *pTree
17230 43 73 72 20 3d 20 70 43 73 72 2d 3e 61 70 54 72  Csr = pCsr->apTr
17240 65 65 43 73 72 5b 69 4b 65 79 2d 43 55 52 53 4f  eeCsr[iKey-CURSO
17250 52 5f 44 41 54 41 5f 54 52 45 45 30 5d 3b 0a 20  R_DATA_TREE0];. 
17260 20 20 20 20 20 6c 73 6d 54 72 65 65 43 75 72 73       lsmTreeCurs
17270 6f 72 4b 65 79 28 70 54 72 65 65 43 73 72 2c 20  orKey(pTreeCsr, 
17280 30 2c 20 70 70 4b 65 79 2c 20 70 6e 4b 65 79 29  0, ppKey, pnKey)
17290 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
172a0 20 20 20 69 6e 74 20 6e 4b 65 79 3b 0a 0a 23 69     int nKey;..#i
172b0 66 6e 64 65 66 20 4e 44 45 42 55 47 0a 20 20 20  fndef NDEBUG.   
172c0 20 20 20 76 6f 69 64 20 2a 70 4b 65 79 3b 0a 20     void *pKey;. 
172d0 20 20 20 20 20 69 6e 74 20 65 54 79 70 65 3b 0a       int eType;.
172e0 20 20 20 20 20 20 6d 75 6c 74 69 43 75 72 73 6f        multiCurso
172f0 72 47 65 74 4b 65 79 28 70 43 73 72 2c 20 69 4b  rGetKey(pCsr, iK
17300 65 79 2c 20 26 65 54 79 70 65 2c 20 26 70 4b 65  ey, &eType, &pKe
17310 79 2c 20 26 6e 4b 65 79 29 3b 0a 20 20 20 20 20  y, &nKey);.     
17320 20 61 73 73 65 72 74 28 20 65 54 79 70 65 3d 3d   assert( eType==
17330 70 43 73 72 2d 3e 65 54 79 70 65 20 29 3b 0a 20  pCsr->eType );. 
17340 20 20 20 20 20 61 73 73 65 72 74 28 20 6e 4b 65       assert( nKe
17350 79 3d 3d 70 43 73 72 2d 3e 6b 65 79 2e 6e 44 61  y==pCsr->key.nDa
17360 74 61 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65  ta );.      asse
17370 72 74 28 20 6d 65 6d 63 6d 70 28 70 4b 65 79 2c  rt( memcmp(pKey,
17380 20 70 43 73 72 2d 3e 6b 65 79 2e 70 44 61 74 61   pCsr->key.pData
17390 2c 20 6e 4b 65 79 29 3d 3d 30 20 29 3b 0a 23 65  , nKey)==0 );.#e
173a0 6e 64 69 66 0a 0a 20 20 20 20 20 20 6e 4b 65 79  ndif..      nKey
173b0 20 3d 20 70 43 73 72 2d 3e 6b 65 79 2e 6e 44 61   = pCsr->key.nDa
173c0 74 61 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 4b  ta;.      if( nK
173d0 65 79 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  ey==0 ){.       
173e0 20 2a 70 70 4b 65 79 20 3d 20 30 3b 0a 20 20 20   *ppKey = 0;.   
173f0 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
17400 20 20 2a 70 70 4b 65 79 20 3d 20 70 43 73 72 2d    *ppKey = pCsr-
17410 3e 6b 65 79 2e 70 44 61 74 61 3b 0a 20 20 20 20  >key.pData;.    
17420 20 20 7d 0a 20 20 20 20 20 20 2a 70 6e 4b 65 79    }.      *pnKey
17430 20 3d 20 6e 4b 65 79 3b 20 0a 20 20 20 20 7d 0a   = nKey; .    }.
17440 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 4c 53 4d    }.  return LSM
17450 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f  _OK;.}../*.** Co
17460 6d 70 61 72 65 20 74 68 65 20 63 75 72 72 65 6e  mpare the curren
17470 74 20 6b 65 79 20 74 68 61 74 20 63 75 72 73 6f  t key that curso
17480 72 20 63 73 72 20 70 6f 69 6e 74 73 20 74 6f 20  r csr points to 
17490 77 69 74 68 20 70 4b 65 79 2f 6e 4b 65 79 2e 20  with pKey/nKey. 
174a0 53 65 74 0a 2a 2a 20 2a 70 69 52 65 73 20 74 6f  Set.** *piRes to
174b0 20 74 68 65 20 72 65 73 75 6c 74 20 61 6e 64 20   the result and 
174c0 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 2e 0a 2a  return LSM_OK..*
174d0 2f 0a 69 6e 74 20 6c 73 6d 5f 63 73 72 5f 63 6d  /.int lsm_csr_cm
174e0 70 28 6c 73 6d 5f 63 75 72 73 6f 72 20 2a 63 73  p(lsm_cursor *cs
174f0 72 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70  r, const void *p
17500 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79 2c 20 69  Key, int nKey, i
17510 6e 74 20 2a 70 69 52 65 73 29 7b 0a 20 20 4d 75  nt *piRes){.  Mu
17520 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 20  ltiCursor *pCsr 
17530 3d 20 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a  = (MultiCursor *
17540 29 63 73 72 3b 0a 20 20 76 6f 69 64 20 2a 70 43  )csr;.  void *pC
17550 73 72 6b 65 79 3b 20 69 6e 74 20 6e 43 73 72 6b  srkey; int nCsrk
17560 65 79 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  ey;.  int rc;.  
17570 72 63 20 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 4b  rc = lsmMCursorK
17580 65 79 28 70 43 73 72 2c 20 26 70 43 73 72 6b 65  ey(pCsr, &pCsrke
17590 79 2c 20 26 6e 43 73 72 6b 65 79 29 3b 0a 20 20  y, &nCsrkey);.  
175a0 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
175b0 7b 0a 20 20 20 20 69 6e 74 20 28 2a 78 43 6d 70  {.    int (*xCmp
175c0 29 28 76 6f 69 64 20 2a 2c 20 69 6e 74 2c 20 76  )(void *, int, v
175d0 6f 69 64 20 2a 2c 20 69 6e 74 29 20 3d 20 70 43  oid *, int) = pC
175e0 73 72 2d 3e 70 44 62 2d 3e 78 43 6d 70 3b 0a 20  sr->pDb->xCmp;. 
175f0 20 20 20 2a 70 69 52 65 73 20 3d 20 73 6f 72 74     *piRes = sort
17600 65 64 4b 65 79 43 6f 6d 70 61 72 65 28 78 43 6d  edKeyCompare(xCm
17610 70 2c 20 30 2c 20 70 43 73 72 6b 65 79 2c 20 6e  p, 0, pCsrkey, n
17620 43 73 72 6b 65 79 2c 20 30 2c 20 28 76 6f 69 64  Csrkey, 0, (void
17630 20 2a 29 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a   *)pKey, nKey);.
17640 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
17650 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 4d 43 75 72 73  .}..int lsmMCurs
17660 6f 72 56 61 6c 75 65 28 4d 75 6c 74 69 43 75 72  orValue(MultiCur
17670 73 6f 72 20 2a 70 43 73 72 2c 20 76 6f 69 64 20  sor *pCsr, void 
17680 2a 2a 70 70 56 61 6c 2c 20 69 6e 74 20 2a 70 6e  **ppVal, int *pn
17690 56 61 6c 29 7b 0a 20 20 76 6f 69 64 20 2a 70 56  Val){.  void *pV
176a0 61 6c 3b 0a 20 20 69 6e 74 20 6e 56 61 6c 3b 0a  al;.  int nVal;.
176b0 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 28 20    int rc;.  if( 
176c0 28 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20 43  (pCsr->flags & C
176d0 55 52 53 4f 52 5f 53 45 45 4b 5f 45 51 29 20 7c  URSOR_SEEK_EQ) |
176e0 7c 20 70 43 73 72 2d 3e 61 54 72 65 65 3d 3d 30  | pCsr->aTree==0
176f0 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 4c 53 4d   ){.    rc = LSM
17700 5f 4f 4b 3b 0a 20 20 20 20 6e 56 61 6c 20 3d 20  _OK;.    nVal = 
17710 70 43 73 72 2d 3e 76 61 6c 2e 6e 44 61 74 61 3b  pCsr->val.nData;
17720 0a 20 20 20 20 70 56 61 6c 20 3d 20 70 43 73 72  .    pVal = pCsr
17730 2d 3e 76 61 6c 2e 70 44 61 74 61 3b 0a 20 20 7d  ->val.pData;.  }
17740 65 6c 73 65 7b 0a 0a 20 20 20 20 61 73 73 65 72  else{..    asser
17750 74 28 20 70 43 73 72 2d 3e 61 54 72 65 65 20 29  t( pCsr->aTree )
17760 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 6d 63  ;.    assert( mc
17770 75 72 73 6f 72 4c 6f 63 61 74 69 6f 6e 4f 6b 28  ursorLocationOk(
17780 70 43 73 72 2c 20 28 70 43 73 72 2d 3e 66 6c 61  pCsr, (pCsr->fla
17790 67 73 20 26 20 43 55 52 53 4f 52 5f 49 47 4e 4f  gs & CURSOR_IGNO
177a0 52 45 5f 44 45 4c 45 54 45 29 29 20 29 3b 0a 0a  RE_DELETE)) );..
177b0 20 20 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75      rc = multiCu
177c0 72 73 6f 72 47 65 74 56 61 6c 28 70 43 73 72 2c  rsorGetVal(pCsr,
177d0 20 70 43 73 72 2d 3e 61 54 72 65 65 5b 31 5d 2c   pCsr->aTree[1],
177e0 20 26 70 56 61 6c 2c 20 26 6e 56 61 6c 29 3b 0a   &pVal, &nVal);.
177f0 20 20 20 20 69 66 28 20 70 56 61 6c 20 26 26 20      if( pVal && 
17800 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20  rc==LSM_OK ){.  
17810 20 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64 42      rc = sortedB
17820 6c 6f 62 53 65 74 28 70 43 73 72 2d 3e 70 44 62  lobSet(pCsr->pDb
17830 2d 3e 70 45 6e 76 2c 20 26 70 43 73 72 2d 3e 76  ->pEnv, &pCsr->v
17840 61 6c 2c 20 70 56 61 6c 2c 20 6e 56 61 6c 29 3b  al, pVal, nVal);
17850 0a 20 20 20 20 20 20 70 56 61 6c 20 3d 20 70 43  .      pVal = pC
17860 73 72 2d 3e 76 61 6c 2e 70 44 61 74 61 3b 0a 20  sr->val.pData;. 
17870 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63     }..    if( rc
17880 21 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20  !=LSM_OK ){.    
17890 20 20 70 56 61 6c 20 3d 20 30 3b 0a 20 20 20 20    pVal = 0;.    
178a0 20 20 6e 56 61 6c 20 3d 20 30 3b 0a 20 20 20 20    nVal = 0;.    
178b0 7d 0a 20 20 7d 0a 20 20 2a 70 70 56 61 6c 20 3d  }.  }.  *ppVal =
178c0 20 70 56 61 6c 3b 0a 20 20 2a 70 6e 56 61 6c 20   pVal;.  *pnVal 
178d0 3d 20 6e 56 61 6c 3b 0a 20 20 72 65 74 75 72 6e  = nVal;.  return
178e0 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 4d   rc;.}..int lsmM
178f0 43 75 72 73 6f 72 54 79 70 65 28 4d 75 6c 74 69  CursorType(Multi
17900 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e  Cursor *pCsr, in
17910 74 20 2a 70 65 54 79 70 65 29 7b 0a 20 20 61 73  t *peType){.  as
17920 73 65 72 74 28 20 70 43 73 72 2d 3e 61 54 72 65  sert( pCsr->aTre
17930 65 20 29 3b 0a 20 20 6d 75 6c 74 69 43 75 72 73  e );.  multiCurs
17940 6f 72 47 65 74 4b 65 79 28 70 43 73 72 2c 20 70  orGetKey(pCsr, p
17950 43 73 72 2d 3e 61 54 72 65 65 5b 31 5d 2c 20 70  Csr->aTree[1], p
17960 65 54 79 70 65 2c 20 30 2c 20 30 29 3b 0a 20 20  eType, 0, 0);.  
17970 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 7d  return LSM_OK;.}
17980 0a 0a 2f 2a 0a 2a 2a 20 42 75 66 66 65 72 20 61  ../*.** Buffer a
17990 44 61 74 61 5b 5d 2c 20 73 69 7a 65 20 6e 44 61  Data[], size nDa
179a0 74 61 2c 20 69 73 20 61 73 73 75 6d 65 64 20 74  ta, is assumed t
179b0 6f 20 63 6f 6e 74 61 69 6e 20 61 20 76 61 6c 69  o contain a vali
179c0 64 20 62 2d 74 72 65 65 20 0a 2a 2a 20 68 69 65  d b-tree .** hie
179d0 72 61 72 63 68 79 20 70 61 67 65 20 69 6d 61 67  rarchy page imag
179e0 65 2e 20 52 65 74 75 72 6e 20 74 68 65 20 6f 66  e. Return the of
179f0 66 73 65 74 20 69 6e 20 61 44 61 74 61 5b 5d 20  fset in aData[] 
17a00 6f 66 20 74 68 65 20 6e 65 78 74 20 66 72 65 65  of the next free
17a10 0a 2a 2a 20 62 79 74 65 20 69 6e 20 74 68 65 20  .** byte in the 
17a20 64 61 74 61 20 61 72 65 61 20 28 77 68 65 72 65  data area (where
17a30 20 61 20 6e 65 77 20 63 65 6c 6c 20 6d 61 79 20   a new cell may 
17a40 62 65 20 77 72 69 74 74 65 6e 20 69 66 20 74 68  be written if th
17a50 65 72 65 20 69 73 0a 2a 2a 20 73 70 61 63 65 29  ere is.** space)
17a60 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
17a70 6d 65 72 67 65 57 6f 72 6b 65 72 50 61 67 65 4f  mergeWorkerPageO
17a80 66 66 73 65 74 28 75 38 20 2a 61 44 61 74 61 2c  ffset(u8 *aData,
17a90 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 69   int nData){.  i
17aa0 6e 74 20 6e 52 65 63 3b 0a 20 20 69 6e 74 20 69  nt nRec;.  int i
17ab0 4f 66 66 3b 0a 20 20 69 6e 74 20 6e 4b 65 79 3b  Off;.  int nKey;
17ac0 0a 20 20 69 6e 74 20 65 54 79 70 65 3b 0a 0a 20  .  int eType;.. 
17ad0 20 6e 52 65 63 20 3d 20 6c 73 6d 47 65 74 55 31   nRec = lsmGetU1
17ae0 36 28 26 61 44 61 74 61 5b 53 45 47 4d 45 4e 54  6(&aData[SEGMENT
17af0 5f 4e 52 45 43 4f 52 44 5f 4f 46 46 53 45 54 28  _NRECORD_OFFSET(
17b00 6e 44 61 74 61 29 5d 29 3b 0a 20 20 69 4f 66 66  nData)]);.  iOff
17b10 20 3d 20 6c 73 6d 47 65 74 55 31 36 28 26 61 44   = lsmGetU16(&aD
17b20 61 74 61 5b 53 45 47 4d 45 4e 54 5f 43 45 4c 4c  ata[SEGMENT_CELL
17b30 50 54 52 5f 4f 46 46 53 45 54 28 6e 44 61 74 61  PTR_OFFSET(nData
17b40 2c 20 6e 52 65 63 2d 31 29 5d 29 3b 0a 20 20 65  , nRec-1)]);.  e
17b50 54 79 70 65 20 3d 20 61 44 61 74 61 5b 69 4f 66  Type = aData[iOf
17b60 66 2b 2b 5d 3b 0a 20 20 61 73 73 65 72 74 28 20  f++];.  assert( 
17b70 65 54 79 70 65 3d 3d 30 20 0a 20 20 20 20 20 20  eType==0 .      
17b80 20 7c 7c 20 65 54 79 70 65 3d 3d 28 4c 53 4d 5f   || eType==(LSM_
17b90 53 59 53 54 45 4d 4b 45 59 7c 4c 53 4d 5f 53 45  SYSTEMKEY|LSM_SE
17ba0 50 41 52 41 54 4f 52 29 20 0a 20 20 20 20 20 20  PARATOR) .      
17bb0 20 7c 7c 20 65 54 79 70 65 3d 3d 28 4c 53 4d 5f   || eType==(LSM_
17bc0 53 45 50 41 52 41 54 4f 52 29 0a 20 20 29 3b 0a  SEPARATOR).  );.
17bd0 0a 20 20 69 4f 66 66 20 2b 3d 20 6c 73 6d 56 61  .  iOff += lsmVa
17be0 72 69 6e 74 47 65 74 33 32 28 26 61 44 61 74 61  rintGet32(&aData
17bf0 5b 69 4f 66 66 5d 2c 20 26 6e 4b 65 79 29 3b 0a  [iOff], &nKey);.
17c00 20 20 69 4f 66 66 20 2b 3d 20 6c 73 6d 56 61 72    iOff += lsmVar
17c10 69 6e 74 47 65 74 33 32 28 26 61 44 61 74 61 5b  intGet32(&aData[
17c20 69 4f 66 66 5d 2c 20 26 6e 4b 65 79 29 3b 0a 0a  iOff], &nKey);..
17c30 20 20 72 65 74 75 72 6e 20 69 4f 66 66 20 2b 20    return iOff + 
17c40 28 65 54 79 70 65 20 3f 20 6e 4b 65 79 20 3a 20  (eType ? nKey : 
17c50 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6f 6c  0);.}../*.** Fol
17c60 6c 6f 77 69 6e 67 20 61 20 63 68 65 63 6b 70 6f  lowing a checkpo
17c70 69 6e 74 20 6f 70 65 72 61 74 69 6f 6e 2c 20 64  int operation, d
17c80 61 74 61 62 61 73 65 20 70 61 67 65 73 20 74 68  atabase pages th
17c90 61 74 20 61 72 65 20 70 61 72 74 20 6f 66 20 74  at are part of t
17ca0 68 65 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74  he.** checkpoint
17cb0 65 64 20 73 74 61 74 65 20 6f 66 20 74 68 65 20  ed state of the 
17cc0 4c 53 4d 20 61 72 65 20 64 65 65 6d 65 64 20 72  LSM are deemed r
17cd0 65 61 64 2d 6f 6e 6c 79 2e 20 54 68 69 73 20 69  ead-only. This i
17ce0 6e 63 6c 75 64 65 73 20 74 68 65 0a 2a 2a 20 72  ncludes the.** r
17cf0 69 67 68 74 2d 6d 6f 73 74 20 70 61 67 65 20 6f  ight-most page o
17d00 66 20 74 68 65 20 62 2d 74 72 65 65 20 68 69 65  f the b-tree hie
17d10 72 61 72 63 68 79 20 6f 66 20 61 6e 79 20 73 65  rarchy of any se
17d20 70 61 72 61 74 6f 72 73 20 61 72 72 61 79 20 75  parators array u
17d30 6e 64 65 72 0a 2a 2a 20 63 6f 6e 73 74 72 75 63  nder.** construc
17d40 74 69 6f 6e 2c 20 61 6e 64 20 61 6c 6c 20 70 61  tion, and all pa
17d50 67 65 73 20 62 65 74 77 65 65 6e 20 69 74 20 61  ges between it a
17d60 6e 64 20 74 68 65 20 62 2d 74 72 65 65 20 72 6f  nd the b-tree ro
17d70 6f 74 2c 20 69 6e 63 6c 75 73 69 76 65 2e 0a 2a  ot, inclusive..*
17d80 2a 20 54 68 69 73 20 69 73 20 61 20 70 72 6f 62  * This is a prob
17d90 6c 65 6d 2c 20 61 73 20 77 68 65 6e 20 66 75 72  lem, as when fur
17da0 74 68 65 72 20 70 61 67 65 73 20 61 72 65 20 61  ther pages are a
17db0 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20 73  ppended to the s
17dc0 65 70 61 72 61 74 6f 72 73 0a 2a 2a 20 61 72 72  eparators.** arr
17dd0 61 79 2c 20 65 6e 74 72 69 65 73 20 6d 75 73 74  ay, entries must
17de0 20 62 65 20 61 64 64 65 64 20 74 6f 20 74 68 65   be added to the
17df0 20 69 6e 64 69 63 61 74 65 64 20 62 2d 74 72 65   indicated b-tre
17e00 65 20 68 69 65 72 61 72 63 68 79 20 70 61 67 65  e hierarchy page
17e10 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75  s..**.** This fu
17e20 6e 63 74 69 6f 6e 20 63 6f 70 69 65 73 20 61 6c  nction copies al
17e30 6c 20 73 75 63 68 20 62 2d 74 72 65 65 20 70 61  l such b-tree pa
17e40 67 65 73 20 74 6f 20 6e 65 77 20 6c 6f 63 61 74  ges to new locat
17e50 69 6f 6e 73 2c 20 73 6f 20 74 68 61 74 0a 2a 2a  ions, so that.**
17e60 20 74 68 65 79 20 63 61 6e 20 62 65 20 6d 6f 64   they can be mod
17e70 69 66 69 65 64 20 61 73 20 72 65 71 75 69 72 65  ified as require
17e80 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f 6d  d..**.** The com
17e90 70 6c 69 63 61 74 69 6f 6e 20 69 73 20 74 68 61  plication is tha
17ea0 74 20 6e 6f 74 20 61 6c 6c 20 64 61 74 61 62 61  t not all databa
17eb0 73 65 20 70 61 67 65 73 20 61 72 65 20 74 68 65  se pages are the
17ec0 20 73 61 6d 65 20 73 69 7a 65 20 2d 20 64 75 65   same size - due
17ed0 0a 2a 2a 20 74 6f 20 74 68 65 20 77 61 79 20 74  .** to the way t
17ee0 68 65 20 66 69 6c 65 2e 63 20 6d 6f 64 75 6c 65  he file.c module
17ef0 20 77 6f 72 6b 73 20 73 6f 6d 65 20 28 74 68 65   works some (the
17f00 20 66 69 72 73 74 20 61 6e 64 20 6c 61 73 74 20   first and last 
17f10 69 6e 20 65 61 63 68 20 62 6c 6f 63 6b 29 0a 2a  in each block).*
17f20 2a 20 61 72 65 20 34 20 62 79 74 65 73 20 73 6d  * are 4 bytes sm
17f30 61 6c 6c 65 72 20 74 68 61 6e 20 74 68 65 20 6f  aller than the o
17f40 74 68 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  thers..*/.static
17f50 20 69 6e 74 20 6d 65 72 67 65 57 6f 72 6b 65 72   int mergeWorker
17f60 4d 6f 76 65 48 69 65 72 61 72 63 68 79 28 0a 20  MoveHierarchy(. 
17f70 20 4d 65 72 67 65 57 6f 72 6b 65 72 20 2a 70 4d   MergeWorker *pM
17f80 57 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  W,              
17f90 20 2f 2a 20 4d 65 72 67 65 20 77 6f 72 6b 65 72   /* Merge worker
17fa0 20 2a 2f 0a 20 20 69 6e 74 20 62 53 65 70 20 20   */.  int bSep  
17fb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17fc0 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 66 6f        /* True fo
17fd0 72 20 73 65 70 61 72 61 74 6f 72 73 20 72 75 6e  r separators run
17fe0 20 2a 2f 0a 29 7b 0a 20 20 6c 73 6d 5f 64 62 20   */.){.  lsm_db 
17ff0 2a 70 44 62 20 3d 20 70 4d 57 2d 3e 70 44 62 3b  *pDb = pMW->pDb;
18000 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
18010 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20  base handle */. 
18020 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
18030 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
18040 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
18050 2a 2f 0a 20 20 69 6e 74 20 69 3b 0a 20 20 50 61  */.  int i;.  Pa
18060 67 65 20 2a 2a 61 70 48 69 65 72 20 3d 20 70 4d  ge **apHier = pM
18070 57 2d 3e 68 69 65 72 2e 61 70 48 69 65 72 3b 0a  W->hier.apHier;.
18080 20 20 69 6e 74 20 6e 48 69 65 72 20 3d 20 70 4d    int nHier = pM
18090 57 2d 3e 68 69 65 72 2e 6e 48 69 65 72 3b 0a 0a  W->hier.nHier;..
180a0 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 4c    for(i=0; rc==L
180b0 53 4d 5f 4f 4b 20 26 26 20 69 3c 6e 48 69 65 72  SM_OK && i<nHier
180c0 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 50 61 67 65  ; i++){.    Page
180d0 20 2a 70 4e 65 77 20 3d 20 30 3b 0a 20 20 20 20   *pNew = 0;.    
180e0 72 63 20 3d 20 6c 73 6d 46 73 53 6f 72 74 65 64  rc = lsmFsSorted
180f0 41 70 70 65 6e 64 28 70 44 62 2d 3e 70 46 53 2c  Append(pDb->pFS,
18100 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2c 20 70   pDb->pWorker, p
18110 4d 57 2d 3e 70 4c 65 76 65 6c 2c 20 31 2c 20 26  MW->pLevel, 1, &
18120 70 4e 65 77 29 3b 0a 20 20 20 20 61 73 73 65 72  pNew);.    asser
18130 74 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 3b  t( rc==LSM_OK );
18140 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53  ..    if( rc==LS
18150 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 75 38  M_OK ){.      u8
18160 20 2a 61 31 3b 20 69 6e 74 20 6e 31 3b 0a 20 20   *a1; int n1;.  
18170 20 20 20 20 75 38 20 2a 61 32 3b 20 69 6e 74 20      u8 *a2; int 
18180 6e 32 3b 0a 0a 20 20 20 20 20 20 61 31 20 3d 20  n2;..      a1 = 
18190 66 73 50 61 67 65 44 61 74 61 28 70 4e 65 77 2c  fsPageData(pNew,
181a0 20 26 6e 31 29 3b 0a 20 20 20 20 20 20 61 32 20   &n1);.      a2 
181b0 3d 20 66 73 50 61 67 65 44 61 74 61 28 61 70 48  = fsPageData(apH
181c0 69 65 72 5b 69 5d 2c 20 26 6e 32 29 3b 0a 0a 20  ier[i], &n2);.. 
181d0 20 20 20 20 20 61 73 73 65 72 74 28 20 6e 31 3d       assert( n1=
181e0 3d 6e 32 20 7c 7c 20 6e 31 2b 34 3d 3d 6e 32 20  =n2 || n1+4==n2 
181f0 29 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 6e 31  );..      if( n1
18200 3d 3d 6e 32 20 29 7b 0a 20 20 20 20 20 20 20 20  ==n2 ){.        
18210 6d 65 6d 63 70 79 28 61 31 2c 20 61 32 2c 20 6e  memcpy(a1, a2, n
18220 32 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  2);.      }else{
18230 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 45 6e  .        int nEn
18240 74 72 79 20 3d 20 70 61 67 65 47 65 74 4e 52 65  try = pageGetNRe
18250 63 28 61 32 2c 20 6e 32 29 3b 0a 20 20 20 20 20  c(a2, n2);.     
18260 20 20 20 69 6e 74 20 69 45 6f 66 31 20 3d 20 53     int iEof1 = S
18270 45 47 4d 45 4e 54 5f 45 4f 46 28 6e 31 2c 20 6e  EGMENT_EOF(n1, n
18280 45 6e 74 72 79 29 3b 0a 20 20 20 20 20 20 20 20  Entry);.        
18290 69 6e 74 20 69 45 6f 66 32 20 3d 20 53 45 47 4d  int iEof2 = SEGM
182a0 45 4e 54 5f 45 4f 46 28 6e 32 2c 20 6e 45 6e 74  ENT_EOF(n2, nEnt
182b0 72 79 29 3b 0a 0a 20 20 20 20 20 20 20 20 6d 65  ry);..        me
182c0 6d 63 70 79 28 61 31 2c 20 61 32 2c 20 69 45 6f  mcpy(a1, a2, iEo
182d0 66 32 20 2d 20 34 29 3b 0a 20 20 20 20 20 20 20  f2 - 4);.       
182e0 20 6d 65 6d 63 70 79 28 26 61 31 5b 69 45 6f 66   memcpy(&a1[iEof
182f0 31 5d 2c 20 26 61 32 5b 69 45 6f 66 32 5d 2c 20  1], &a2[iEof2], 
18300 6e 32 20 2d 20 69 45 6f 66 32 29 3b 0a 20 20 20  n2 - iEof2);.   
18310 20 20 20 7d 0a 0a 20 20 20 20 20 20 6c 73 6d 46     }..      lsmF
18320 73 50 61 67 65 52 65 6c 65 61 73 65 28 61 70 48  sPageRelease(apH
18330 69 65 72 5b 69 5d 29 3b 0a 20 20 20 20 20 20 61  ier[i]);.      a
18340 70 48 69 65 72 5b 69 5d 20 3d 20 70 4e 65 77 3b  pHier[i] = pNew;
18350 0a 0a 23 69 66 20 30 0a 20 20 20 20 20 20 61 73  ..#if 0.      as
18360 73 65 72 74 28 20 6e 31 3d 3d 6e 32 20 7c 7c 20  sert( n1==n2 || 
18370 6e 31 2b 34 3d 3d 6e 32 20 7c 7c 20 6e 32 2b 34  n1+4==n2 || n2+4
18380 3d 3d 6e 31 20 29 3b 0a 20 20 20 20 20 20 69 66  ==n1 );.      if
18390 28 20 6e 31 3e 3d 6e 32 20 29 7b 0a 20 20 20 20  ( n1>=n2 ){.    
183a0 20 20 20 20 2f 2a 20 49 66 20 6e 31 20 28 73 69      /* If n1 (si
183b0 7a 65 20 6f 66 20 74 68 65 20 6e 65 77 20 70 61  ze of the new pa
183c0 67 65 29 20 69 73 20 65 71 75 61 6c 20 74 6f 20  ge) is equal to 
183d0 6f 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  or greater than 
183e0 6e 32 20 28 74 68 65 0a 20 20 20 20 20 20 20 20  n2 (the.        
183f0 2a 2a 20 73 69 7a 65 20 6f 66 20 74 68 65 20 6f  ** size of the o
18400 6c 64 20 70 61 67 65 29 2c 20 74 68 65 6e 20 63  ld page), then c
18410 6f 70 79 20 74 68 65 20 64 61 74 61 20 69 6e 74  opy the data int
18420 6f 20 74 68 65 20 6e 65 77 20 70 61 67 65 2e 20  o the new page. 
18430 49 66 0a 20 20 20 20 20 20 20 20 2a 2a 20 6e 31  If.        ** n1
18440 3d 3d 6e 32 2c 20 74 68 69 73 20 63 6f 75 6c 64  ==n2, this could
18450 20 62 65 20 64 6f 6e 65 20 77 69 74 68 20 61 20   be done with a 
18460 73 69 6e 67 6c 65 20 6d 65 6d 63 70 79 28 29 2e  single memcpy().
18470 20 48 6f 77 65 76 65 72 2c 20 0a 20 20 20 20 20   However, .     
18480 20 20 20 2a 2a 20 73 69 6e 63 65 20 73 6f 6d 65     ** since some
18490 74 69 6d 65 73 20 6e 31 3e 6e 32 2c 20 74 68 65  times n1>n2, the
184a0 20 70 61 67 65 20 63 6f 6e 74 65 6e 74 20 61 6e   page content an
184b0 64 20 66 6f 6f 74 65 72 20 6d 75 73 74 20 62 65  d footer must be
184c0 20 63 6f 70 69 65 64 20 0a 20 20 20 20 20 20 20   copied .       
184d0 20 2a 2a 20 73 65 70 61 72 61 74 65 6c 79 2e 20   ** separately. 
184e0 2a 2f 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e  */.        int n
184f0 45 6e 74 72 79 20 3d 20 70 61 67 65 47 65 74 4e  Entry = pageGetN
18500 52 65 63 28 61 32 2c 20 6e 32 29 3b 0a 20 20 20  Rec(a2, n2);.   
18510 20 20 20 20 20 69 6e 74 20 69 45 6f 66 31 20 3d       int iEof1 =
18520 20 53 45 47 4d 45 4e 54 5f 45 4f 46 28 6e 31 2c   SEGMENT_EOF(n1,
18530 20 6e 45 6e 74 72 79 29 3b 0a 20 20 20 20 20 20   nEntry);.      
18540 20 20 69 6e 74 20 69 45 6f 66 32 20 3d 20 53 45    int iEof2 = SE
18550 47 4d 45 4e 54 5f 45 4f 46 28 6e 32 2c 20 6e 45  GMENT_EOF(n2, nE
18560 6e 74 72 79 29 3b 0a 20 20 20 20 20 20 20 20 6d  ntry);.        m
18570 65 6d 63 70 79 28 61 31 2c 20 61 32 2c 20 69 45  emcpy(a1, a2, iE
18580 6f 66 32 29 3b 0a 20 20 20 20 20 20 20 20 6d 65  of2);.        me
18590 6d 63 70 79 28 26 61 31 5b 69 45 6f 66 31 5d 2c  mcpy(&a1[iEof1],
185a0 20 26 61 32 5b 69 45 6f 66 32 5d 2c 20 6e 32 20   &a2[iEof2], n2 
185b0 2d 20 69 45 6f 66 32 29 3b 0a 20 20 20 20 20 20  - iEof2);.      
185c0 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61    lsmFsPageRelea
185d0 73 65 28 61 70 48 69 65 72 5b 69 5d 29 3b 0a 20  se(apHier[i]);. 
185e0 20 20 20 20 20 20 20 61 70 48 69 65 72 5b 69 5d         apHier[i]
185f0 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20 20 20 7d   = pNew;.      }
18600 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 6c 73  else{.        ls
18610 6d 50 75 74 55 31 36 28 26 61 31 5b 53 45 47 4d  mPutU16(&a1[SEGM
18620 45 4e 54 5f 46 4c 41 47 53 5f 4f 46 46 53 45 54  ENT_FLAGS_OFFSET
18630 28 6e 31 29 5d 2c 20 53 45 47 4d 45 4e 54 5f 42  (n1)], SEGMENT_B
18640 54 52 45 45 5f 46 4c 41 47 29 3b 0a 20 20 20 20  TREE_FLAG);.    
18650 20 20 20 20 6c 73 6d 50 75 74 55 31 36 28 26 61      lsmPutU16(&a
18660 31 5b 53 45 47 4d 45 4e 54 5f 4e 52 45 43 4f 52  1[SEGMENT_NRECOR
18670 44 5f 4f 46 46 53 45 54 28 6e 31 29 5d 2c 20 30  D_OFFSET(n1)], 0
18680 29 3b 0a 20 20 20 20 20 20 20 20 6c 73 6d 50 75  );.        lsmPu
18690 74 55 36 34 28 26 61 31 5b 53 45 47 4d 45 4e 54  tU64(&a1[SEGMENT
186a0 5f 50 4f 49 4e 54 45 52 5f 4f 46 46 53 45 54 28  _POINTER_OFFSET(
186b0 6e 31 29 5d 2c 20 30 29 3b 0a 20 20 20 20 20 20  n1)], 0);.      
186c0 20 20 69 20 3d 20 69 20 2d 20 31 3b 0a 20 20 20    i = i - 1;.   
186d0 20 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65       lsmFsPageRe
186e0 6c 65 61 73 65 28 70 4e 65 77 29 3b 0a 20 20 20  lease(pNew);.   
186f0 20 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 20 20     }.#endif.    
18700 7d 0a 20 20 7d 0a 0a 23 69 66 64 65 66 20 4c 53  }.  }..#ifdef LS
18710 4d 5f 44 45 42 55 47 0a 20 20 69 66 28 20 72 63  M_DEBUG.  if( rc
18720 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20  ==LSM_OK ){.    
18730 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 48 69 65 72  for(i=0; i<nHier
18740 3b 20 69 2b 2b 29 20 61 73 73 65 72 74 28 20 6c  ; i++) assert( l
18750 73 6d 46 73 50 61 67 65 57 72 69 74 61 62 6c 65  smFsPageWritable
18760 28 61 70 48 69 65 72 5b 69 5d 29 20 29 3b 0a 20  (apHier[i]) );. 
18770 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 72 65 74   }.#endif..  ret
18780 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
18790 20 41 6c 6c 6f 63 61 74 65 20 61 6e 64 20 70 6f   Allocate and po
187a0 70 75 6c 61 74 65 20 74 68 65 20 4d 65 72 67 65  pulate the Merge
187b0 57 6f 72 6b 65 72 2e 61 70 48 69 65 72 5b 5d 20  Worker.apHier[] 
187c0 61 72 72 61 79 2e 0a 2a 2f 0a 73 74 61 74 69 63  array..*/.static
187d0 20 69 6e 74 20 6d 65 72 67 65 57 6f 72 6b 65 72   int mergeWorker
187e0 4c 6f 61 64 48 69 65 72 61 72 63 68 79 28 4d 65  LoadHierarchy(Me
187f0 72 67 65 57 6f 72 6b 65 72 20 2a 70 4d 57 29 7b  rgeWorker *pMW){
18800 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f  .  int rc = LSM_
18810 4f 4b 3b 0a 20 20 53 65 67 6d 65 6e 74 20 2a 70  OK;.  Segment *p
18820 53 65 67 3b 0a 20 20 48 69 65 72 61 72 63 68 79  Seg;.  Hierarchy
18830 20 2a 70 3b 0a 20 0a 20 20 70 53 65 67 20 3d 20   *p;. .  pSeg = 
18840 26 70 4d 57 2d 3e 70 4c 65 76 65 6c 2d 3e 6c 68  &pMW->pLevel->lh
18850 73 3b 0a 20 20 70 20 3d 20 26 70 4d 57 2d 3e 68  s;.  p = &pMW->h
18860 69 65 72 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 61  ier;..  if( p->a
18870 70 48 69 65 72 3d 3d 30 20 26 26 20 70 53 65 67  pHier==0 && pSeg
18880 2d 3e 69 52 6f 6f 74 21 3d 30 20 29 7b 0a 20 20  ->iRoot!=0 ){.  
18890 20 20 46 69 6c 65 53 79 73 74 65 6d 20 2a 70 46    FileSystem *pF
188a0 53 20 3d 20 70 4d 57 2d 3e 70 44 62 2d 3e 70 46  S = pMW->pDb->pF
188b0 53 3b 0a 20 20 20 20 6c 73 6d 5f 65 6e 76 20 2a  S;.    lsm_env *
188c0 70 45 6e 76 20 3d 20 70 4d 57 2d 3e 70 44 62 2d  pEnv = pMW->pDb-
188d0 3e 70 45 6e 76 3b 0a 20 20 20 20 50 61 67 65 20  >pEnv;.    Page 
188e0 2a 2a 61 70 48 69 65 72 20 3d 20 30 3b 0a 20 20  **apHier = 0;.  
188f0 20 20 69 6e 74 20 6e 48 69 65 72 20 3d 20 30 3b    int nHier = 0;
18900 0a 20 20 20 20 69 6e 74 20 69 50 67 20 3d 20 28  .    int iPg = (
18910 69 6e 74 29 70 53 65 67 2d 3e 69 52 6f 6f 74 3b  int)pSeg->iRoot;
18920 0a 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20 20  ..    do {.     
18930 20 50 61 67 65 20 2a 70 50 67 20 3d 20 30 3b 0a   Page *pPg = 0;.
18940 20 20 20 20 20 20 75 38 20 2a 61 44 61 74 61 3b        u8 *aData;
18950 0a 20 20 20 20 20 20 69 6e 74 20 6e 44 61 74 61  .      int nData
18960 3b 0a 20 20 20 20 20 20 69 6e 74 20 66 6c 61 67  ;.      int flag
18970 73 3b 0a 0a 20 20 20 20 20 20 72 63 20 3d 20 6c  s;..      rc = l
18980 73 6d 46 73 44 62 50 61 67 65 47 65 74 28 70 46  smFsDbPageGet(pF
18990 53 2c 20 70 53 65 67 2c 20 69 50 67 2c 20 26 70  S, pSeg, iPg, &p
189a0 50 67 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  Pg);.      if( r
189b0 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 62 72 65 61  c!=LSM_OK ) brea
189c0 6b 3b 0a 0a 20 20 20 20 20 20 61 44 61 74 61 20  k;..      aData 
189d0 3d 20 66 73 50 61 67 65 44 61 74 61 28 70 50 67  = fsPageData(pPg
189e0 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 20  , &nData);.     
189f0 20 66 6c 61 67 73 20 3d 20 70 61 67 65 47 65 74   flags = pageGet
18a00 46 6c 61 67 73 28 61 44 61 74 61 2c 20 6e 44 61  Flags(aData, nDa
18a10 74 61 29 3b 0a 20 20 20 20 20 20 69 66 28 20 66  ta);.      if( f
18a20 6c 61 67 73 26 53 45 47 4d 45 4e 54 5f 42 54 52  lags&SEGMENT_BTR
18a30 45 45 5f 46 4c 41 47 20 29 7b 0a 20 20 20 20 20  EE_FLAG ){.     
18a40 20 20 20 50 61 67 65 20 2a 2a 61 70 4e 65 77 20     Page **apNew 
18a50 3d 20 28 50 61 67 65 20 2a 2a 29 6c 73 6d 52 65  = (Page **)lsmRe
18a60 61 6c 6c 6f 63 28 0a 20 20 20 20 20 20 20 20 20  alloc(.         
18a70 20 20 20 70 45 6e 76 2c 20 61 70 48 69 65 72 2c     pEnv, apHier,
18a80 20 73 69 7a 65 6f 66 28 50 61 67 65 20 2a 29 2a   sizeof(Page *)*
18a90 28 6e 48 69 65 72 2b 31 29 0a 20 20 20 20 20 20  (nHier+1).      
18aa0 20 20 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28    );.        if(
18ab0 20 61 70 4e 65 77 3d 3d 30 20 29 7b 0a 20 20 20   apNew==0 ){.   
18ac0 20 20 20 20 20 20 20 72 63 20 3d 20 4c 53 4d 5f         rc = LSM_
18ad0 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20 20 20  NOMEM_BKPT;.    
18ae0 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
18af0 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 61       }.        a
18b00 70 48 69 65 72 20 3d 20 61 70 4e 65 77 3b 0a 20  pHier = apNew;. 
18b10 20 20 20 20 20 20 20 6d 65 6d 6d 6f 76 65 28 26         memmove(&
18b20 61 70 48 69 65 72 5b 31 5d 2c 20 26 61 70 48 69  apHier[1], &apHi
18b30 65 72 5b 30 5d 2c 20 73 69 7a 65 6f 66 28 50 61  er[0], sizeof(Pa
18b40 67 65 20 2a 29 20 2a 20 6e 48 69 65 72 29 3b 0a  ge *) * nHier);.
18b50 20 20 20 20 20 20 20 20 6e 48 69 65 72 2b 2b 3b          nHier++;
18b60 0a 0a 20 20 20 20 20 20 20 20 61 70 48 69 65 72  ..        apHier
18b70 5b 30 5d 20 3d 20 70 50 67 3b 0a 20 20 20 20 20  [0] = pPg;.     
18b80 20 20 20 69 50 67 20 3d 20 28 69 6e 74 29 70 61     iPg = (int)pa
18b90 67 65 47 65 74 50 74 72 28 61 44 61 74 61 2c 20  geGetPtr(aData, 
18ba0 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20 7d 65  nData);.      }e
18bb0 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 6c 73 6d  lse{.        lsm
18bc0 46 73 50 61 67 65 52 65 6c 65 61 73 65 28 70 50  FsPageRelease(pP
18bd0 67 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  g);.        brea
18be0 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k;.      }.    }
18bf0 77 68 69 6c 65 28 20 31 20 29 3b 0a 0a 20 20 20  while( 1 );..   
18c00 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
18c10 29 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 44 61  ){.      u8 *aDa
18c20 74 61 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 44  ta;.      int nD
18c30 61 74 61 3b 0a 20 20 20 20 20 20 61 44 61 74 61  ata;.      aData
18c40 20 3d 20 66 73 50 61 67 65 44 61 74 61 28 61 70   = fsPageData(ap
18c50 48 69 65 72 5b 30 5d 2c 20 26 6e 44 61 74 61 29  Hier[0], &nData)
18c60 3b 0a 20 20 20 20 20 20 70 4d 57 2d 3e 61 53 61  ;.      pMW->aSa
18c70 76 65 5b 30 5d 2e 69 50 67 6e 6f 20 3d 20 70 61  ve[0].iPgno = pa
18c80 67 65 47 65 74 50 74 72 28 61 44 61 74 61 2c 20  geGetPtr(aData, 
18c90 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20 70 2d  nData);.      p-
18ca0 3e 6e 48 69 65 72 20 3d 20 6e 48 69 65 72 3b 0a  >nHier = nHier;.
18cb0 20 20 20 20 20 20 70 2d 3e 61 70 48 69 65 72 20        p->apHier 
18cc0 3d 20 61 70 48 69 65 72 3b 0a 20 20 20 20 20 20  = apHier;.      
18cd0 72 63 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65 72  rc = mergeWorker
18ce0 4d 6f 76 65 48 69 65 72 61 72 63 68 79 28 70 4d  MoveHierarchy(pM
18cf0 57 2c 20 30 29 3b 0a 20 20 20 20 7d 65 6c 73 65  W, 0);.    }else
18d00 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20  {.      int i;. 
18d10 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c       for(i=0; i<
18d20 6e 48 69 65 72 3b 20 69 2b 2b 29 7b 0a 20 20 20  nHier; i++){.   
18d30 20 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65       lsmFsPageRe
18d40 6c 65 61 73 65 28 61 70 48 69 65 72 5b 69 5d 29  lease(apHier[i])
18d50 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
18d60 6c 73 6d 46 72 65 65 28 70 45 6e 76 2c 20 61 70  lsmFree(pEnv, ap
18d70 48 69 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  Hier);.    }.  }
18d80 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
18d90 0a 0a 2f 2a 0a 2a 2a 20 42 2d 74 72 65 65 20 70  ../*.** B-tree p
18da0 61 67 65 73 20 75 73 65 20 61 6c 6d 6f 73 74 20  ages use almost 
18db0 74 68 65 20 73 61 6d 65 20 66 6f 72 6d 61 74 20  the same format 
18dc0 61 73 20 72 65 67 75 6c 61 72 20 70 61 67 65 73  as regular pages
18dd0 2e 20 54 68 65 20 0a 2a 2a 20 64 69 66 66 65 72  . The .** differ
18de0 65 6e 63 65 73 20 61 72 65 3a 0a 2a 2a 0a 2a 2a  ences are:.**.**
18df0 20 20 20 31 2e 20 54 68 65 20 72 65 63 6f 72 64     1. The record
18e00 20 66 6f 72 6d 61 74 20 69 73 20 28 75 73 75 61   format is (usua
18e10 6c 6c 79 2c 20 73 65 65 20 62 65 6c 6f 77 29 20  lly, see below) 
18e20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a  as follows:.**.*
18e30 2a 20 20 20 20 20 20 20 20 20 2b 20 54 79 70 65  *         + Type
18e40 20 62 79 74 65 20 28 61 6c 77 61 79 73 20 53 4f   byte (always SO
18e50 52 54 45 44 5f 53 45 50 41 52 41 54 4f 52 20 6f  RTED_SEPARATOR o
18e60 72 20 53 4f 52 54 45 44 5f 53 59 53 54 45 4d 5f  r SORTED_SYSTEM_
18e70 53 45 50 41 52 41 54 4f 52 29 2c 0a 2a 2a 20 20  SEPARATOR),.**  
18e80 20 20 20 20 20 20 20 2b 20 41 62 73 6f 6c 75 74         + Absolut
18e90 65 20 70 6f 69 6e 74 65 72 20 76 61 6c 75 65 20  e pointer value 
18ea0 28 76 61 72 69 6e 74 29 2c 0a 2a 2a 20 20 20 20  (varint),.**    
18eb0 20 20 20 20 20 2b 20 4e 75 6d 62 65 72 20 6f 66       + Number of
18ec0 20 62 79 74 65 73 20 69 6e 20 6b 65 79 20 28 76   bytes in key (v
18ed0 61 72 69 6e 74 29 2c 0a 2a 2a 20 20 20 20 20 20  arint),.**      
18ee0 20 20 20 2b 20 4c 73 6d 42 6c 6f 62 20 63 6f 6e     + LsmBlob con
18ef0 74 61 69 6e 69 6e 67 20 6b 65 79 20 64 61 74 61  taining key data
18f00 2e 0a 2a 2a 0a 2a 2a 20 20 20 32 2e 20 41 6c 6c  ..**.**   2. All
18f10 20 70 6f 69 6e 74 65 72 20 76 61 6c 75 65 73 20   pointer values 
18f20 61 72 65 20 73 74 6f 72 65 64 20 61 73 20 61 62  are stored as ab
18f30 73 6f 6c 75 74 65 20 76 61 6c 75 65 73 20 28 6e  solute values (n
18f40 6f 74 20 6f 66 66 73 65 74 73 20 0a 2a 2a 20 20  ot offsets .**  
18f50 20 20 20 20 72 65 6c 61 74 69 76 65 20 74 6f 20      relative to 
18f60 74 68 65 20 66 6f 6f 74 65 72 20 70 6f 69 6e 74  the footer point
18f70 65 72 20 76 61 6c 75 65 29 2e 0a 2a 2a 0a 2a 2a  er value)..**.**
18f80 20 20 20 33 2e 20 45 61 63 68 20 70 6f 69 6e 74     3. Each point
18f90 65 72 20 74 68 61 74 20 69 73 20 70 61 72 74 20  er that is part 
18fa0 6f 66 20 61 20 72 65 63 6f 72 64 20 70 6f 69 6e  of a record poin
18fb0 74 73 20 74 6f 20 61 20 70 61 67 65 20 74 68 61  ts to a page tha
18fc0 74 20 0a 2a 2a 20 20 20 20 20 20 63 6f 6e 74 61  t .**      conta
18fd0 69 6e 73 20 6b 65 79 73 20 73 6d 61 6c 6c 65 72  ins keys smaller
18fe0 20 74 68 61 6e 20 74 68 65 20 72 65 63 6f 72 64   than the record
18ff0 73 20 6b 65 79 20 28 6e 6f 74 65 3a 20 6e 6f 74  s key (note: not
19000 20 22 65 71 75 61 6c 20 74 6f 20 6f 72 0a 2a 2a   "equal to or.**
19010 20 20 20 20 20 20 73 6d 61 6c 6c 65 72 20 74 68        smaller th
19020 61 6e 20 2d 20 73 6d 61 6c 6c 65 72 20 74 68 61  an - smaller tha
19030 6e 22 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 34 2e 20  n")..**.**   4. 
19040 54 68 65 20 70 6f 69 6e 74 65 72 20 69 6e 20 74  The pointer in t
19050 68 65 20 70 61 67 65 20 66 6f 6f 74 65 72 20 6f  he page footer o
19060 66 20 61 20 62 2d 74 72 65 65 20 70 61 67 65 20  f a b-tree page 
19070 70 6f 69 6e 74 73 20 74 6f 20 61 20 70 61 67 65  points to a page
19080 0a 2a 2a 20 20 20 20 20 20 74 68 61 74 20 63 6f  .**      that co
19090 6e 74 61 69 6e 73 20 6b 65 79 73 20 65 71 75 61  ntains keys equa
190a0 6c 20 74 6f 20 6f 72 20 6c 61 72 67 65 72 20 74  l to or larger t
190b0 68 61 6e 20 74 68 65 20 6c 61 72 67 65 73 74 20  han the largest 
190c0 6b 65 79 20 6f 6e 20 74 68 65 0a 2a 2a 20 20 20  key on the.**   
190d0 20 20 20 62 2d 74 72 65 65 20 70 61 67 65 2e 0a     b-tree page..
190e0 2a 2a 0a 2a 2a 20 54 68 65 20 72 65 61 73 6f 6e  **.** The reason
190f0 20 66 6f 72 20 68 61 76 69 6e 67 20 74 68 65 20   for having the 
19100 70 61 67 65 20 66 6f 6f 74 65 72 20 70 6f 69 6e  page footer poin
19110 74 65 72 20 70 6f 69 6e 74 20 74 6f 20 74 68 65  ter point to the
19120 20 72 69 67 68 74 2d 63 68 69 6c 64 0a 2a 2a 20   right-child.** 
19130 28 69 6e 73 74 65 61 64 20 6f 66 20 74 68 65 20  (instead of the 
19140 6c 65 66 74 29 20 69 73 20 74 68 61 74 20 64 6f  left) is that do
19150 69 6e 67 20 74 68 69 6e 67 73 20 74 68 69 73 20  ing things this 
19160 77 61 79 20 6d 61 6b 65 73 20 74 68 65 20 0a 2a  way makes the .*
19170 2a 20 6d 65 72 67 65 57 6f 72 6b 65 72 4d 6f 76  * mergeWorkerMov
19180 65 48 69 65 72 61 72 63 68 79 28 29 20 6f 70 65  eHierarchy() ope
19190 72 61 74 69 6f 6e 20 6c 65 73 73 20 63 6f 6d 70  ration less comp
191a0 6c 69 63 61 74 65 64 20 28 73 69 6e 63 65 20 74  licated (since t
191b0 68 65 20 70 6f 69 6e 74 65 72 73 20 0a 2a 2a 20  he pointers .** 
191c0 74 68 61 74 20 6e 65 65 64 20 74 6f 20 62 65 20  that need to be 
191d0 75 70 64 61 74 65 64 20 61 72 65 20 61 6c 6c 20  updated are all 
191e0 73 74 6f 72 65 64 20 61 73 20 66 69 78 65 64 2d  stored as fixed-
191f0 73 69 7a 65 20 69 6e 74 65 67 65 72 73 20 77 69  size integers wi
19200 74 68 69 6e 20 74 68 65 20 0a 2a 2a 20 70 61 67  thin the .** pag
19210 65 20 66 6f 6f 74 65 72 2c 20 6e 6f 74 20 76 61  e footer, not va
19220 72 69 6e 74 73 20 69 6e 20 70 61 67 65 20 72 65  rints in page re
19230 63 6f 72 64 73 29 2e 0a 2a 2a 0a 2a 2a 20 52 65  cords)..**.** Re
19240 63 6f 72 64 73 20 6d 61 79 20 6e 6f 74 20 73 70  cords may not sp
19250 61 6e 20 62 2d 74 72 65 65 20 70 61 67 65 73 2e  an b-tree pages.
19260 20 49 66 20 74 68 69 73 20 66 75 6e 63 74 69 6f   If this functio
19270 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 61  n is called to a
19280 64 64 20 61 0a 2a 2a 20 72 65 63 6f 72 64 20 6c  dd a.** record l
19290 61 72 67 65 72 20 74 68 61 6e 20 28 70 61 67 65  arger than (page
192a0 2d 73 69 7a 65 20 2f 20 34 29 20 62 79 74 65 73  -size / 4) bytes
192b0 2c 20 74 68 65 6e 20 61 20 70 6f 69 6e 74 65 72  , then a pointer
192c0 20 74 6f 20 74 68 65 20 69 6e 64 65 78 65 64 0a   to the indexed.
192d0 2a 2a 20 61 72 72 61 79 20 70 61 67 65 20 74 68  ** array page th
192e0 61 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  at contains the 
192f0 6d 61 69 6e 20 72 65 63 6f 72 64 20 69 73 20 61  main record is a
19300 64 64 65 64 20 74 6f 20 74 68 65 20 62 2d 74 72  dded to the b-tr
19310 65 65 20 69 6e 73 74 65 61 64 2e 0a 2a 2a 20 49  ee instead..** I
19320 6e 20 74 68 69 73 20 63 61 73 65 20 74 68 65 20  n this case the 
19330 72 65 63 6f 72 64 20 66 6f 72 6d 61 74 20 69 73  record format is
19340 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 20 20  :.**.**         
19350 2b 20 30 78 30 30 20 62 79 74 65 20 28 31 20 62  + 0x00 byte (1 b
19360 79 74 65 29 20 0a 2a 2a 20 20 20 20 20 20 20 20  yte) .**        
19370 20 2b 20 41 62 73 6f 6c 75 74 65 20 70 6f 69 6e   + Absolute poin
19380 74 65 72 20 76 61 6c 75 65 20 28 76 61 72 69 6e  ter value (varin
19390 74 29 2c 0a 2a 2a 20 20 20 20 20 20 20 20 20 2b  t),.**         +
193a0 20 41 62 73 6f 6c 75 74 65 20 70 61 67 65 20 6e   Absolute page n
193b0 75 6d 62 65 72 20 6f 66 20 70 61 67 65 20 63 6f  umber of page co
193c0 6e 74 61 69 6e 69 6e 67 20 6b 65 79 20 28 76 61  ntaining key (va
193d0 72 69 6e 74 29 2e 0a 2a 2a 0a 2a 2a 20 53 65 65  rint)..**.** See
193e0 20 66 75 6e 63 74 69 6f 6e 20 73 65 65 6b 49 6e   function seekIn
193f0 42 74 72 65 65 28 29 20 66 6f 72 20 74 68 65 20  Btree() for the 
19400 63 6f 64 65 20 74 68 61 74 20 74 72 61 76 65 72  code that traver
19410 73 65 73 20 62 2d 74 72 65 65 20 70 61 67 65 73  ses b-tree pages
19420 2e 0a 2a 2f 0a 0a 73 74 61 74 69 63 20 69 6e 74  ..*/..static int
19430 20 6d 65 72 67 65 57 6f 72 6b 65 72 42 74 72 65   mergeWorkerBtre
19440 65 57 72 69 74 65 28 0a 20 20 4d 65 72 67 65 57  eWrite(.  MergeW
19450 6f 72 6b 65 72 20 2a 70 4d 57 2c 0a 20 20 75 38  orker *pMW,.  u8
19460 20 65 54 79 70 65 2c 0a 20 20 4c 73 6d 50 67 6e   eType,.  LsmPgn
19470 6f 20 69 50 74 72 2c 0a 20 20 4c 73 6d 50 67 6e  o iPtr,.  LsmPgn
19480 6f 20 69 4b 65 79 50 67 2c 0a 20 20 76 6f 69 64  o iKeyPg,.  void
19490 20 2a 70 4b 65 79 2c 0a 20 20 69 6e 74 20 6e 4b   *pKey,.  int nK
194a0 65 79 0a 29 7b 0a 20 20 48 69 65 72 61 72 63 68  ey.){.  Hierarch
194b0 79 20 2a 70 20 3d 20 26 70 4d 57 2d 3e 68 69 65  y *p = &pMW->hie
194c0 72 3b 0a 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62  r;.  lsm_db *pDb
194d0 20 3d 20 70 4d 57 2d 3e 70 44 62 3b 20 20 20 20   = pMW->pDb;    
194e0 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
194f0 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74   handle */.  int
19500 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20   rc = LSM_OK;   
19510 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
19520 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20  Return Code */. 
19530 20 69 6e 74 20 69 4c 65 76 65 6c 3b 20 20 20 20   int iLevel;    
19540 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19550 20 2f 2a 20 4c 65 76 65 6c 20 6f 66 20 62 2d 74   /* Level of b-t
19560 72 65 65 20 68 69 65 72 61 63 68 79 20 74 6f 20  ree hierachy to 
19570 77 72 69 74 65 20 74 6f 20 2a 2f 0a 20 20 69 6e  write to */.  in
19580 74 20 6e 44 61 74 61 3b 20 20 20 20 20 20 20 20  t nData;        
19590 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
195a0 20 53 69 7a 65 20 6f 66 20 61 44 61 74 61 5b 5d   Size of aData[]
195b0 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75   in bytes */.  u
195c0 38 20 2a 61 44 61 74 61 3b 20 20 20 20 20 20 20  8 *aData;       
195d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
195e0 2a 20 50 61 67 65 20 64 61 74 61 20 66 6f 72 20  * Page data for 
195f0 6c 65 76 65 6c 20 69 4c 65 76 65 6c 20 2a 2f 0a  level iLevel */.
19600 20 20 69 6e 74 20 69 4f 66 66 3b 20 20 20 20 20    int iOff;     
19610 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19620 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f 6e 20 62    /* Offset on b
19630 2d 74 72 65 65 20 70 61 67 65 20 74 6f 20 77 72  -tree page to wr
19640 69 74 65 20 72 65 63 6f 72 64 20 74 6f 20 2a 2f  ite record to */
19650 0a 20 20 69 6e 74 20 6e 52 65 63 3b 20 20 20 20  .  int nRec;    
19660 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19670 20 20 20 2f 2a 20 49 6e 69 74 69 61 6c 20 6e 75     /* Initial nu
19680 6d 62 65 72 20 6f 66 20 72 65 63 6f 72 64 73 20  mber of records 
19690 6f 6e 20 62 2d 74 72 65 65 20 70 61 67 65 20 2a  on b-tree page *
196a0 2f 0a 0a 20 20 2f 2a 20 69 4b 65 79 50 67 20 73  /..  /* iKeyPg s
196b0 68 6f 75 6c 64 20 62 65 20 7a 65 72 6f 20 66 6f  hould be zero fo
196c0 72 20 61 6e 20 6f 72 64 69 6e 61 72 79 20 62 2d  r an ordinary b-
196d0 74 72 65 65 20 6b 65 79 2c 20 6f 72 20 6e 6f 6e  tree key, or non
196e0 2d 7a 65 72 6f 20 66 6f 72 20 61 6e 0a 20 20 2a  -zero for an.  *
196f0 2a 20 69 6e 64 69 72 65 63 74 20 6b 65 79 2e 20  * indirect key. 
19700 54 68 65 20 66 6c 61 67 73 20 62 79 74 65 20 66  The flags byte f
19710 6f 72 20 61 6e 20 69 6e 64 69 72 65 63 74 20 6b  or an indirect k
19720 65 79 20 69 73 20 30 78 30 30 2e 20 20 2a 2f 0a  ey is 0x00.  */.
19730 20 20 61 73 73 65 72 74 28 20 28 65 54 79 70 65    assert( (eType
19740 3d 3d 30 29 3d 3d 28 69 4b 65 79 50 67 21 3d 30  ==0)==(iKeyPg!=0
19750 29 20 29 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 4d  ) );..  /* The M
19760 65 72 67 65 57 6f 72 6b 65 72 2e 61 70 48 69 65  ergeWorker.apHie
19770 72 5b 5d 20 61 72 72 61 79 20 63 6f 6e 74 61 69  r[] array contai
19780 6e 73 20 74 68 65 20 72 69 67 68 74 2d 6d 6f 73  ns the right-mos
19790 74 20 6c 65 61 66 20 6f 66 20 74 68 65 20 62 2d  t leaf of the b-
197a0 74 72 65 65 0a 20 20 2a 2a 20 68 69 65 72 61 72  tree.  ** hierar
197b0 63 68 79 2c 20 74 68 65 20 72 6f 6f 74 20 6e 6f  chy, the root no
197c0 64 65 2c 20 61 6e 64 20 61 6c 6c 20 6e 6f 64 65  de, and all node
197d0 73 20 74 68 61 74 20 6c 69 65 20 6f 6e 20 74 68  s that lie on th
197e0 65 20 70 61 74 68 20 62 65 74 77 65 65 6e 2e 0a  e path between..
197f0 20 20 2a 2a 20 61 70 48 69 65 72 5b 30 5d 20 69    ** apHier[0] i
19800 73 20 74 68 65 20 72 69 67 68 74 2d 6d 6f 73 74  s the right-most
19810 20 6c 65 61 66 20 61 6e 64 20 61 70 48 69 65 72   leaf and apHier
19820 5b 70 4d 57 2d 3e 6e 48 69 65 72 2d 31 5d 20 69  [pMW->nHier-1] i
19830 73 20 74 68 65 20 63 75 72 72 65 6e 74 0a 20 20  s the current.  
19840 2a 2a 20 72 6f 6f 74 20 70 61 67 65 2e 0a 20 20  ** root page..  
19850 2a 2a 0a 20 20 2a 2a 20 54 68 69 73 20 6c 6f 6f  **.  ** This loo
19860 70 20 73 65 61 72 63 68 65 73 20 66 6f 72 20 61  p searches for a
19870 20 6e 6f 64 65 20 77 69 74 68 20 65 6e 6f 75 67   node with enoug
19880 68 20 73 70 61 63 65 20 74 6f 20 73 74 6f 72 65  h space to store
19890 20 74 68 65 20 6b 65 79 20 6f 6e 2c 0a 20 20 2a   the key on,.  *
198a0 2a 20 73 74 61 72 74 69 6e 67 20 77 69 74 68 20  * starting with 
198b0 74 68 65 20 6c 65 61 66 20 61 6e 64 20 69 74 65  the leaf and ite
198c0 72 61 74 69 6e 67 20 75 70 20 74 6f 77 61 72 64  rating up toward
198d0 73 20 74 68 65 20 72 6f 6f 74 2e 20 57 68 65 6e  s the root. When
198e0 20 74 68 65 20 6c 6f 6f 70 0a 20 20 2a 2a 20 65   the loop.  ** e
198f0 78 69 74 73 2c 20 74 68 65 20 6b 65 79 20 6d 61  xits, the key ma
19900 79 20 62 65 20 77 72 69 74 74 65 6e 20 74 6f 20  y be written to 
19910 61 70 48 69 65 72 5b 69 4c 65 76 65 6c 5d 2e 20  apHier[iLevel]. 
19920 20 2a 2f 0a 20 20 66 6f 72 28 69 4c 65 76 65 6c   */.  for(iLevel
19930 3d 30 3b 20 69 4c 65 76 65 6c 3c 3d 70 2d 3e 6e  =0; iLevel<=p->n
19940 48 69 65 72 3b 20 69 4c 65 76 65 6c 2b 2b 29 7b  Hier; iLevel++){
19950 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 20  .    int nByte; 
19960 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19970 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
19980 66 72 65 65 20 62 79 74 65 73 20 72 65 71 75 69  free bytes requi
19990 72 65 64 20 2a 2f 0a 0a 20 20 20 20 69 66 28 20  red */..    if( 
199a0 69 4c 65 76 65 6c 3d 3d 70 2d 3e 6e 48 69 65 72  iLevel==p->nHier
199b0 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 45 78 74   ){.      /* Ext
199c0 65 6e 64 20 74 68 65 20 61 72 72 61 79 20 61 6e  end the array an
199d0 64 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  d allocate a new
199e0 20 72 6f 6f 74 20 70 61 67 65 2e 20 2a 2f 0a 20   root page. */. 
199f0 20 20 20 20 20 50 61 67 65 20 2a 2a 61 4e 65 77       Page **aNew
19a00 3b 0a 20 20 20 20 20 20 61 4e 65 77 20 3d 20 28  ;.      aNew = (
19a10 50 61 67 65 20 2a 2a 29 6c 73 6d 52 65 61 6c 6c  Page **)lsmReall
19a20 6f 63 28 0a 20 20 20 20 20 20 20 20 20 20 70 4d  oc(.          pM
19a30 57 2d 3e 70 44 62 2d 3e 70 45 6e 76 2c 20 70 2d  W->pDb->pEnv, p-
19a40 3e 61 70 48 69 65 72 2c 20 73 69 7a 65 6f 66 28  >apHier, sizeof(
19a50 50 61 67 65 20 2a 29 2a 28 70 2d 3e 6e 48 69 65  Page *)*(p->nHie
19a60 72 2b 31 29 0a 20 20 20 20 20 20 29 3b 0a 20 20  r+1).      );.  
19a70 20 20 20 20 69 66 28 20 21 61 4e 65 77 20 29 7b      if( !aNew ){
19a80 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
19a90 4c 53 4d 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a  LSM_NOMEM_BKPT;.
19aa0 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 2d        }.      p-
19ab0 3e 61 70 48 69 65 72 20 3d 20 61 4e 65 77 3b 0a  >apHier = aNew;.
19ac0 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
19ad0 20 50 61 67 65 20 2a 70 4f 6c 64 3b 0a 20 20 20   Page *pOld;.   
19ae0 20 20 20 69 6e 74 20 6e 46 72 65 65 3b 0a 0a 20     int nFree;.. 
19af0 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 6b       /* If the k
19b00 65 79 20 77 69 6c 6c 20 66 69 74 20 6f 6e 20 74  ey will fit on t
19b10 68 69 73 20 70 61 67 65 2c 20 62 72 65 61 6b 20  his page, break 
19b20 6f 75 74 20 6f 66 20 74 68 65 20 6c 6f 6f 70 20  out of the loop 
19b30 68 65 72 65 2e 0a 20 20 20 20 20 20 2a 2a 20 54  here..      ** T
19b40 68 65 20 6e 65 77 20 65 6e 74 72 79 20 77 69 6c  he new entry wil
19b50 6c 20 62 65 20 77 72 69 74 74 65 6e 20 74 6f 20  l be written to 
19b60 70 61 67 65 20 61 70 48 69 65 72 5b 69 4c 65 76  page apHier[iLev
19b70 65 6c 5d 2e 20 2a 2f 0a 20 20 20 20 20 20 70 4f  el]. */.      pO
19b80 6c 64 20 3d 20 70 2d 3e 61 70 48 69 65 72 5b 69  ld = p->apHier[i
19b90 4c 65 76 65 6c 5d 3b 0a 20 20 20 20 20 20 61 73  Level];.      as
19ba0 73 65 72 74 28 20 6c 73 6d 46 73 50 61 67 65 57  sert( lsmFsPageW
19bb0 72 69 74 61 62 6c 65 28 70 4f 6c 64 29 20 29 3b  ritable(pOld) );
19bc0 0a 20 20 20 20 20 20 61 44 61 74 61 20 3d 20 66  .      aData = f
19bd0 73 50 61 67 65 44 61 74 61 28 70 4f 6c 64 2c 20  sPageData(pOld, 
19be0 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20 69  &nData);.      i
19bf0 66 28 20 65 54 79 70 65 3d 3d 30 20 29 7b 0a 20  f( eType==0 ){. 
19c00 20 20 20 20 20 20 20 6e 42 79 74 65 20 3d 20 32         nByte = 2
19c10 20 2b 20 31 20 2b 20 6c 73 6d 56 61 72 69 6e 74   + 1 + lsmVarint
19c20 4c 65 6e 33 32 28 28 69 6e 74 29 69 50 74 72 29  Len32((int)iPtr)
19c30 20 2b 20 6c 73 6d 56 61 72 69 6e 74 4c 65 6e 33   + lsmVarintLen3
19c40 32 28 28 69 6e 74 29 69 4b 65 79 50 67 29 3b 0a  2((int)iKeyPg);.
19c50 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
19c60 20 20 20 20 20 6e 42 79 74 65 20 3d 20 32 20 2b       nByte = 2 +
19c70 20 31 20 2b 20 6c 73 6d 56 61 72 69 6e 74 4c 65   1 + lsmVarintLe
19c80 6e 33 32 28 28 69 6e 74 29 69 50 74 72 29 20 2b  n32((int)iPtr) +
19c90 20 6c 73 6d 56 61 72 69 6e 74 4c 65 6e 33 32 28   lsmVarintLen32(
19ca0 6e 4b 65 79 29 20 2b 20 6e 4b 65 79 3b 0a 20 20  nKey) + nKey;.  
19cb0 20 20 20 20 7d 0a 20 20 20 20 20 20 6e 52 65 63      }.      nRec
19cc0 20 3d 20 70 61 67 65 47 65 74 4e 52 65 63 28 61   = pageGetNRec(a
19cd0 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20  Data, nData);.  
19ce0 20 20 20 20 6e 46 72 65 65 20 3d 20 53 45 47 4d      nFree = SEGM
19cf0 45 4e 54 5f 45 4f 46 28 6e 44 61 74 61 2c 20 6e  ENT_EOF(nData, n
19d00 52 65 63 29 20 2d 20 6d 65 72 67 65 57 6f 72 6b  Rec) - mergeWork
19d10 65 72 50 61 67 65 4f 66 66 73 65 74 28 61 44 61  erPageOffset(aDa
19d20 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20 20  ta, nData);.    
19d30 20 20 69 66 28 20 6e 42 79 74 65 3c 3d 6e 46 72    if( nByte<=nFr
19d40 65 65 20 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20  ee ) break;..   
19d50 20 20 20 2f 2a 20 4f 74 68 65 72 77 69 73 65 2c     /* Otherwise,
19d60 20 74 68 69 73 20 70 61 67 65 20 69 73 20 66 75   this page is fu
19d70 6c 6c 2e 20 53 65 74 20 74 68 65 20 72 69 67 68  ll. Set the righ
19d80 74 2d 68 61 6e 64 2d 63 68 69 6c 64 20 70 6f 69  t-hand-child poi
19d90 6e 74 65 72 0a 20 20 20 20 20 20 2a 2a 20 74 6f  nter.      ** to
19da0 20 69 50 74 72 20 61 6e 64 20 72 65 6c 65 61 73   iPtr and releas
19db0 65 20 69 74 2e 20 20 2a 2f 0a 20 20 20 20 20 20  e it.  */.      
19dc0 6c 73 6d 50 75 74 55 36 34 28 26 61 44 61 74 61  lsmPutU64(&aData
19dd0 5b 53 45 47 4d 45 4e 54 5f 50 4f 49 4e 54 45 52  [SEGMENT_POINTER
19de0 5f 4f 46 46 53 45 54 28 6e 44 61 74 61 29 5d 2c  _OFFSET(nData)],
19df0 20 69 50 74 72 29 3b 0a 20 20 20 20 20 20 61 73   iPtr);.      as
19e00 73 65 72 74 28 20 6c 73 6d 46 73 50 61 67 65 4e  sert( lsmFsPageN
19e10 75 6d 62 65 72 28 70 4f 6c 64 29 3d 3d 30 20 29  umber(pOld)==0 )
19e20 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d  ;.      rc = lsm
19e30 46 73 50 61 67 65 50 65 72 73 69 73 74 28 70 4f  FsPagePersist(pO
19e40 6c 64 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  ld);.      if( r
19e50 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
19e60 20 20 20 20 20 69 50 74 72 20 3d 20 6c 73 6d 46       iPtr = lsmF
19e70 73 50 61 67 65 4e 75 6d 62 65 72 28 70 4f 6c 64  sPageNumber(pOld
19e80 29 3b 0a 20 20 20 20 20 20 20 20 6c 73 6d 46 73  );.        lsmFs
19e90 50 61 67 65 52 65 6c 65 61 73 65 28 70 4f 6c 64  PageRelease(pOld
19ea0 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
19eb0 0a 0a 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  ..    /* Allocat
19ec0 65 20 61 20 6e 65 77 20 70 61 67 65 20 66 6f 72  e a new page for
19ed0 20 61 70 48 69 65 72 5b 69 4c 65 76 65 6c 5d 2e   apHier[iLevel].
19ee0 20 2a 2f 0a 20 20 20 20 70 2d 3e 61 70 48 69 65   */.    p->apHie
19ef0 72 5b 69 4c 65 76 65 6c 5d 20 3d 20 30 3b 0a 20  r[iLevel] = 0;. 
19f00 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
19f10 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  K ){.      rc = 
19f20 6c 73 6d 46 73 53 6f 72 74 65 64 41 70 70 65 6e  lsmFsSortedAppen
19f30 64 28 0a 20 20 20 20 20 20 20 20 20 20 70 44 62  d(.          pDb
19f40 2d 3e 70 46 53 2c 20 70 44 62 2d 3e 70 57 6f 72  ->pFS, pDb->pWor
19f50 6b 65 72 2c 20 70 4d 57 2d 3e 70 4c 65 76 65 6c  ker, pMW->pLevel
19f60 2c 20 31 2c 20 26 70 2d 3e 61 70 48 69 65 72 5b  , 1, &p->apHier[
19f70 69 4c 65 76 65 6c 5d 0a 20 20 20 20 20 20 29 3b  iLevel].      );
19f80 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72  .    }.    if( r
19f90 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65 74 75  c!=LSM_OK ) retu
19fa0 72 6e 20 72 63 3b 0a 0a 20 20 20 20 61 44 61 74  rn rc;..    aDat
19fb0 61 20 3d 20 66 73 50 61 67 65 44 61 74 61 28 70  a = fsPageData(p
19fc0 2d 3e 61 70 48 69 65 72 5b 69 4c 65 76 65 6c 5d  ->apHier[iLevel]
19fd0 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 6d  , &nData);.    m
19fe0 65 6d 73 65 74 28 61 44 61 74 61 2c 20 30 2c 20  emset(aData, 0, 
19ff0 6e 44 61 74 61 29 3b 0a 20 20 20 20 6c 73 6d 50  nData);.    lsmP
1a000 75 74 55 31 36 28 26 61 44 61 74 61 5b 53 45 47  utU16(&aData[SEG
1a010 4d 45 4e 54 5f 46 4c 41 47 53 5f 4f 46 46 53 45  MENT_FLAGS_OFFSE
1a020 54 28 6e 44 61 74 61 29 5d 2c 20 53 45 47 4d 45  T(nData)], SEGME
1a030 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 29 3b 0a  NT_BTREE_FLAG);.
1a040 20 20 20 20 6c 73 6d 50 75 74 55 31 36 28 26 61      lsmPutU16(&a
1a050 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f 4e 52 45  Data[SEGMENT_NRE
1a060 43 4f 52 44 5f 4f 46 46 53 45 54 28 6e 44 61 74  CORD_OFFSET(nDat
1a070 61 29 5d 2c 20 30 29 3b 0a 0a 20 20 20 20 69 66  a)], 0);..    if
1a080 28 20 69 4c 65 76 65 6c 3d 3d 70 2d 3e 6e 48 69  ( iLevel==p->nHi
1a090 65 72 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 6e  er ){.      p->n
1a0a0 48 69 65 72 2b 2b 3b 0a 20 20 20 20 20 20 62 72  Hier++;.      br
1a0b0 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  eak;.    }.  }..
1a0c0 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 6b    /* Write the k
1a0d0 65 79 20 69 6e 74 6f 20 70 61 67 65 20 61 70 48  ey into page apH
1a0e0 69 65 72 5b 69 4c 65 76 65 6c 5d 2e 20 2a 2f 0a  ier[iLevel]. */.
1a0f0 20 20 61 44 61 74 61 20 3d 20 66 73 50 61 67 65    aData = fsPage
1a100 44 61 74 61 28 70 2d 3e 61 70 48 69 65 72 5b 69  Data(p->apHier[i
1a110 4c 65 76 65 6c 5d 2c 20 26 6e 44 61 74 61 29 3b  Level], &nData);
1a120 0a 20 20 69 4f 66 66 20 3d 20 6d 65 72 67 65 57  .  iOff = mergeW
1a130 6f 72 6b 65 72 50 61 67 65 4f 66 66 73 65 74 28  orkerPageOffset(
1a140 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20  aData, nData);. 
1a150 20 6e 52 65 63 20 3d 20 70 61 67 65 47 65 74 4e   nRec = pageGetN
1a160 52 65 63 28 61 44 61 74 61 2c 20 6e 44 61 74 61  Rec(aData, nData
1a170 29 3b 0a 20 20 6c 73 6d 50 75 74 55 31 36 28 26  );.  lsmPutU16(&
1a180 61 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f 43 45  aData[SEGMENT_CE
1a190 4c 4c 50 54 52 5f 4f 46 46 53 45 54 28 6e 44 61  LLPTR_OFFSET(nDa
1a1a0 74 61 2c 20 6e 52 65 63 29 5d 2c 20 28 75 31 36  ta, nRec)], (u16
1a1b0 29 69 4f 66 66 29 3b 0a 20 20 6c 73 6d 50 75 74  )iOff);.  lsmPut
1a1c0 55 31 36 28 26 61 44 61 74 61 5b 53 45 47 4d 45  U16(&aData[SEGME
1a1d0 4e 54 5f 4e 52 45 43 4f 52 44 5f 4f 46 46 53 45  NT_NRECORD_OFFSE
1a1e0 54 28 6e 44 61 74 61 29 5d 2c 20 28 75 31 36 29  T(nData)], (u16)
1a1f0 28 6e 52 65 63 2b 31 29 29 3b 0a 20 20 69 66 28  (nRec+1));.  if(
1a200 20 65 54 79 70 65 3d 3d 30 20 29 7b 0a 20 20 20   eType==0 ){.   
1a210 20 61 44 61 74 61 5b 69 4f 66 66 2b 2b 5d 20 3d   aData[iOff++] =
1a220 20 30 78 30 30 3b 0a 20 20 20 20 69 4f 66 66 20   0x00;.    iOff 
1a230 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 50 75 74 33  += lsmVarintPut3
1a240 32 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c 20  2(&aData[iOff], 
1a250 28 69 6e 74 29 69 50 74 72 29 3b 0a 20 20 20 20  (int)iPtr);.    
1a260 69 4f 66 66 20 2b 3d 20 6c 73 6d 56 61 72 69 6e  iOff += lsmVarin
1a270 74 50 75 74 33 32 28 26 61 44 61 74 61 5b 69 4f  tPut32(&aData[iO
1a280 66 66 5d 2c 20 28 69 6e 74 29 69 4b 65 79 50 67  ff], (int)iKeyPg
1a290 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
1a2a0 61 44 61 74 61 5b 69 4f 66 66 2b 2b 5d 20 3d 20  aData[iOff++] = 
1a2b0 65 54 79 70 65 3b 0a 20 20 20 20 69 4f 66 66 20  eType;.    iOff 
1a2c0 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 50 75 74 33  += lsmVarintPut3
1a2d0 32 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c 20  2(&aData[iOff], 
1a2e0 28 69 6e 74 29 69 50 74 72 29 3b 0a 20 20 20 20  (int)iPtr);.    
1a2f0 69 4f 66 66 20 2b 3d 20 6c 73 6d 56 61 72 69 6e  iOff += lsmVarin
1a300 74 50 75 74 33 32 28 26 61 44 61 74 61 5b 69 4f  tPut32(&aData[iO
1a310 66 66 5d 2c 20 6e 4b 65 79 29 3b 0a 20 20 20 20  ff], nKey);.    
1a320 6d 65 6d 63 70 79 28 26 61 44 61 74 61 5b 69 4f  memcpy(&aData[iO
1a330 66 66 5d 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29  ff], pKey, nKey)
1a340 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
1a350 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  rc;.}..static in
1a360 74 20 6d 65 72 67 65 57 6f 72 6b 65 72 42 74 72  t mergeWorkerBtr
1a370 65 65 49 6e 64 69 72 65 63 74 28 4d 65 72 67 65  eeIndirect(Merge
1a380 57 6f 72 6b 65 72 20 2a 70 4d 57 29 7b 0a 20 20  Worker *pMW){.  
1a390 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b  int rc = LSM_OK;
1a3a0 0a 20 20 69 66 28 20 70 4d 57 2d 3e 69 49 6e 64  .  if( pMW->iInd
1a3b0 69 72 65 63 74 20 29 7b 0a 20 20 20 20 4c 73 6d  irect ){.    Lsm
1a3c0 50 67 6e 6f 20 69 4b 65 79 50 67 20 3d 20 70 4d  Pgno iKeyPg = pM
1a3d0 57 2d 3e 61 53 61 76 65 5b 31 5d 2e 69 50 67 6e  W->aSave[1].iPgn
1a3e0 6f 3b 0a 20 20 20 20 72 63 20 3d 20 6d 65 72 67  o;.    rc = merg
1a3f0 65 57 6f 72 6b 65 72 42 74 72 65 65 57 72 69 74  eWorkerBtreeWrit
1a400 65 28 70 4d 57 2c 20 30 2c 20 70 4d 57 2d 3e 69  e(pMW, 0, pMW->i
1a410 49 6e 64 69 72 65 63 74 2c 20 69 4b 65 79 50 67  Indirect, iKeyPg
1a420 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 70 4d 57  , 0, 0);.    pMW
1a430 2d 3e 69 49 6e 64 69 72 65 63 74 20 3d 20 30 3b  ->iIndirect = 0;
1a440 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
1a450 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e  ;.}../*.** Appen
1a460 64 20 74 68 65 20 64 61 74 61 62 61 73 65 20 6b  d the database k
1a470 65 79 20 28 69 54 6f 70 69 63 2f 70 4b 65 79 2f  ey (iTopic/pKey/
1a480 6e 4b 65 79 29 20 74 6f 20 74 68 65 20 62 2d 74  nKey) to the b-t
1a490 72 65 65 20 75 6e 64 65 72 20 0a 2a 2a 20 63 6f  ree under .** co
1a4a0 6e 73 74 72 75 63 74 69 6f 6e 2e 20 54 68 69 73  nstruction. This
1a4b0 20 6b 65 79 20 68 61 73 20 6e 6f 74 20 79 65 74   key has not yet
1a4c0 20 62 65 65 6e 20 77 72 69 74 74 65 6e 20 74 6f   been written to
1a4d0 20 61 20 73 65 67 6d 65 6e 74 20 70 61 67 65 2e   a segment page.
1a4e0 0a 2a 2a 20 54 68 65 20 70 6f 69 6e 74 65 72 20  .** The pointer 
1a4f0 74 68 61 74 20 77 69 6c 6c 20 61 63 63 6f 6d 70  that will accomp
1a500 61 6e 79 20 74 68 65 20 6e 65 77 20 6b 65 79 20  any the new key 
1a510 69 6e 20 74 68 65 20 62 2d 74 72 65 65 20 2d 20  in the b-tree - 
1a520 74 68 61 74 0a 2a 2a 20 70 6f 69 6e 74 73 20 74  that.** points t
1a530 6f 20 74 68 65 20 63 6f 6d 70 6c 65 74 65 64 20  o the completed 
1a540 73 65 67 6d 65 6e 74 20 70 61 67 65 20 74 68 61  segment page tha
1a550 74 20 63 6f 6e 74 61 69 6e 73 20 6b 65 79 73 20  t contains keys 
1a560 73 6d 61 6c 6c 65 72 20 74 68 61 6e 0a 2a 2a 20  smaller than.** 
1a570 28 70 4b 65 79 2f 6e 4b 65 79 29 20 69 73 20 63  (pKey/nKey) is c
1a580 75 72 72 65 6e 74 6c 79 20 73 74 6f 72 65 64 20  urrently stored 
1a590 69 6e 20 70 4d 57 2d 3e 61 53 61 76 65 5b 30 5d  in pMW->aSave[0]
1a5a0 2e 69 50 67 6e 6f 2e 0a 2a 2f 0a 73 74 61 74 69  .iPgno..*/.stati
1a5b0 63 20 69 6e 74 20 6d 65 72 67 65 57 6f 72 6b 65  c int mergeWorke
1a5c0 72 50 75 73 68 48 69 65 72 61 72 63 68 79 28 0a  rPushHierarchy(.
1a5d0 20 20 4d 65 72 67 65 57 6f 72 6b 65 72 20 2a 70    MergeWorker *p
1a5e0 4d 57 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  MW,             
1a5f0 20 20 2f 2a 20 4d 65 72 67 65 20 77 6f 72 6b 65    /* Merge worke
1a600 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e  r object */.  in
1a610 74 20 69 54 6f 70 69 63 2c 20 20 20 20 20 20 20  t iTopic,       
1a620 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1a630 20 54 6f 70 69 63 20 76 61 6c 75 65 20 66 6f 72   Topic value for
1a640 20 74 68 69 73 20 6b 65 79 20 2a 2f 0a 20 20 76   this key */.  v
1a650 6f 69 64 20 2a 70 4b 65 79 2c 20 20 20 20 20 20  oid *pKey,      
1a660 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1a670 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 6b 65 79  * Pointer to key
1a680 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74   buffer */.  int
1a690 20 6e 4b 65 79 20 20 20 20 20 20 20 20 20 20 20   nKey           
1a6a0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1a6b0 53 69 7a 65 20 6f 66 20 70 4b 65 79 20 62 75 66  Size of pKey buf
1a6c0 66 65 72 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  fer in bytes */.
1a6d0 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53  ){.  int rc = LS
1a6e0 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  M_OK;           
1a6f0 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43       /* Return C
1a700 6f 64 65 20 2a 2f 0a 20 20 4c 73 6d 50 67 6e 6f  ode */.  LsmPgno
1a710 20 69 50 74 72 3b 20 20 20 20 20 20 20 20 20 20   iPtr;          
1a720 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
1a730 74 65 72 20 76 61 6c 75 65 20 74 6f 20 61 63 63  ter value to acc
1a740 6f 6d 70 61 6e 79 20 70 4b 65 79 2f 6e 4b 65 79  ompany pKey/nKey
1a750 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70   */..  assert( p
1a760 4d 57 2d 3e 61 53 61 76 65 5b 30 5d 2e 62 53 74  MW->aSave[0].bSt
1a770 6f 72 65 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  ore==0 );.  asse
1a780 72 74 28 20 70 4d 57 2d 3e 61 53 61 76 65 5b 31  rt( pMW->aSave[1
1a790 5d 2e 62 53 74 6f 72 65 3d 3d 30 20 29 3b 0a 20  ].bStore==0 );. 
1a7a0 20 72 63 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65   rc = mergeWorke
1a7b0 72 42 74 72 65 65 49 6e 64 69 72 65 63 74 28 70  rBtreeIndirect(p
1a7c0 4d 57 29 3b 0a 0a 20 20 2f 2a 20 4f 62 74 61 69  MW);..  /* Obtai
1a7d0 6e 20 74 68 65 20 61 62 73 6f 6c 75 74 65 20 70  n the absolute p
1a7e0 6f 69 6e 74 65 72 20 76 61 6c 75 65 20 74 6f 20  ointer value to 
1a7f0 73 74 6f 72 65 20 61 6c 6f 6e 67 20 77 69 74 68  store along with
1a800 20 74 68 65 20 6b 65 79 20 69 6e 20 74 68 65 0a   the key in the.
1a810 20 20 2a 2a 20 70 61 67 65 20 62 6f 64 79 2e 20    ** page body. 
1a820 54 68 69 73 20 70 6f 69 6e 74 65 72 20 70 6f 69  This pointer poi
1a830 6e 74 73 20 74 6f 20 61 20 70 61 67 65 20 74 68  nts to a page th
1a840 61 74 20 63 6f 6e 74 61 69 6e 73 20 6b 65 79 73  at contains keys
1a850 20 74 68 61 74 20 61 72 65 0a 20 20 2a 2a 20 73   that are.  ** s
1a860 6d 61 6c 6c 65 72 20 74 68 61 6e 20 70 4b 65 79  maller than pKey
1a870 2f 6e 4b 65 79 2e 20 20 2a 2f 0a 20 20 69 50 74  /nKey.  */.  iPt
1a880 72 20 3d 20 70 4d 57 2d 3e 61 53 61 76 65 5b 30  r = pMW->aSave[0
1a890 5d 2e 69 50 67 6e 6f 3b 0a 20 20 61 73 73 65 72  ].iPgno;.  asser
1a8a0 74 28 20 69 50 74 72 21 3d 30 20 29 3b 0a 0a 20  t( iPtr!=0 );.. 
1a8b0 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20 69 66   /* Determine if
1a8c0 20 74 68 65 20 69 6e 64 69 72 65 63 74 20 66 6f   the indirect fo
1a8d0 72 6d 61 74 20 73 68 6f 75 6c 64 20 62 65 20 75  rmat should be u
1a8e0 73 65 64 2e 20 2a 2f 0a 20 20 69 66 28 20 28 6e  sed. */.  if( (n
1a8f0 4b 65 79 2a 34 20 3e 20 6c 73 6d 46 73 50 61 67  Key*4 > lsmFsPag
1a900 65 53 69 7a 65 28 70 4d 57 2d 3e 70 44 62 2d 3e  eSize(pMW->pDb->
1a910 70 46 53 29 29 20 29 7b 0a 20 20 20 20 70 4d 57  pFS)) ){.    pMW
1a920 2d 3e 69 49 6e 64 69 72 65 63 74 20 3d 20 69 50  ->iIndirect = iP
1a930 74 72 3b 0a 20 20 20 20 70 4d 57 2d 3e 61 53 61  tr;.    pMW->aSa
1a940 76 65 5b 31 5d 2e 62 53 74 6f 72 65 20 3d 20 31  ve[1].bStore = 1
1a950 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72  ;.  }else{.    r
1a960 63 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65 72 42  c = mergeWorkerB
1a970 74 72 65 65 57 72 69 74 65 28 0a 20 20 20 20 20  treeWrite(.     
1a980 20 20 20 70 4d 57 2c 20 28 75 38 29 28 69 54 6f     pMW, (u8)(iTo
1a990 70 69 63 20 7c 20 4c 53 4d 5f 53 45 50 41 52 41  pic | LSM_SEPARA
1a9a0 54 4f 52 29 2c 20 69 50 74 72 2c 20 30 2c 20 70  TOR), iPtr, 0, p
1a9b0 4b 65 79 2c 20 6e 4b 65 79 0a 20 20 20 20 29 3b  Key, nKey.    );
1a9c0 0a 20 20 7d 0a 0a 20 20 2f 2a 20 45 6e 73 75 72  .  }..  /* Ensur
1a9d0 65 20 74 68 61 74 20 74 68 65 20 53 6f 72 74 65  e that the Sorte
1a9e0 64 52 75 6e 2e 69 52 6f 6f 74 20 66 69 65 6c 64  dRun.iRoot field
1a9f0 20 69 73 20 63 6f 72 72 65 63 74 2e 20 2a 2f 0a   is correct. */.
1aa00 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
1aa10 73 74 61 74 69 63 20 69 6e 74 20 6d 65 72 67 65  static int merge
1aa20 57 6f 72 6b 65 72 46 69 6e 69 73 68 48 69 65 72  WorkerFinishHier
1aa30 61 72 63 68 79 28 0a 20 20 4d 65 72 67 65 57 6f  archy(.  MergeWo
1aa40 72 6b 65 72 20 2a 70 4d 57 20 20 20 20 20 20 20  rker *pMW       
1aa50 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67           /* Merg
1aa60 65 20 77 6f 72 6b 65 72 20 6f 62 6a 65 63 74 20  e worker object 
1aa70 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 20 20  */.){.  int i;  
1aa80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1aa90 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20          /* Used 
1aaa0 74 6f 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20  to loop through 
1aab0 61 70 48 69 65 72 5b 5d 20 2a 2f 0a 20 20 69 6e  apHier[] */.  in
1aac0 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20  t rc = LSM_OK;  
1aad0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1aae0 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
1aaf0 20 20 4c 73 6d 50 67 6e 6f 20 69 50 74 72 3b 20    LsmPgno iPtr; 
1ab00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ab10 20 20 2f 2a 20 4e 65 77 20 72 69 67 68 74 2d 68    /* New right-h
1ab20 61 6e 64 2d 63 68 69 6c 64 20 70 6f 69 6e 74 65  and-child pointe
1ab30 72 20 76 61 6c 75 65 20 2a 2f 0a 0a 20 20 69 50  r value */..  iP
1ab40 74 72 20 3d 20 70 4d 57 2d 3e 61 53 61 76 65 5b  tr = pMW->aSave[
1ab50 30 5d 2e 69 50 67 6e 6f 3b 0a 20 20 66 6f 72 28  0].iPgno;.  for(
1ab60 69 3d 30 3b 20 69 3c 70 4d 57 2d 3e 68 69 65 72  i=0; i<pMW->hier
1ab70 2e 6e 48 69 65 72 20 26 26 20 72 63 3d 3d 4c 53  .nHier && rc==LS
1ab80 4d 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  M_OK; i++){.    
1ab90 50 61 67 65 20 2a 70 50 67 20 3d 20 70 4d 57 2d  Page *pPg = pMW-
1aba0 3e 68 69 65 72 2e 61 70 48 69 65 72 5b 69 5d 3b  >hier.apHier[i];
1abb0 0a 20 20 20 20 69 6e 74 20 6e 44 61 74 61 3b 20  .    int nData; 
1abc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1abd0 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 44     /* Size of aD
1abe0 61 74 61 5b 5d 20 69 6e 20 62 79 74 65 73 20 2a  ata[] in bytes *
1abf0 2f 0a 20 20 20 20 75 38 20 2a 61 44 61 74 61 3b  /.    u8 *aData;
1ac00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ac10 20 20 20 20 2f 2a 20 50 61 67 65 20 64 61 74 61      /* Page data
1ac20 20 66 6f 72 20 70 50 67 20 2a 2f 0a 0a 20 20 20   for pPg */..   
1ac30 20 61 44 61 74 61 20 3d 20 66 73 50 61 67 65 44   aData = fsPageD
1ac40 61 74 61 28 70 50 67 2c 20 26 6e 44 61 74 61 29  ata(pPg, &nData)
1ac50 3b 0a 20 20 20 20 6c 73 6d 50 75 74 55 36 34 28  ;.    lsmPutU64(
1ac60 26 61 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f 50  &aData[SEGMENT_P
1ac70 4f 49 4e 54 45 52 5f 4f 46 46 53 45 54 28 6e 44  OINTER_OFFSET(nD
1ac80 61 74 61 29 5d 2c 20 69 50 74 72 29 3b 0a 0a 20  ata)], iPtr);.. 
1ac90 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 50 61 67     rc = lsmFsPag
1aca0 65 50 65 72 73 69 73 74 28 70 50 67 29 3b 0a 20  ePersist(pPg);. 
1acb0 20 20 20 69 50 74 72 20 3d 20 6c 73 6d 46 73 50     iPtr = lsmFsP
1acc0 61 67 65 4e 75 6d 62 65 72 28 70 50 67 29 3b 0a  ageNumber(pPg);.
1acd0 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c      lsmFsPageRel
1ace0 65 61 73 65 28 70 50 67 29 3b 0a 20 20 7d 0a 0a  ease(pPg);.  }..
1acf0 20 20 69 66 28 20 70 4d 57 2d 3e 68 69 65 72 2e    if( pMW->hier.
1ad00 6e 48 69 65 72 20 29 7b 0a 20 20 20 20 70 4d 57  nHier ){.    pMW
1ad10 2d 3e 70 4c 65 76 65 6c 2d 3e 6c 68 73 2e 69 52  ->pLevel->lhs.iR
1ad20 6f 6f 74 20 3d 20 69 50 74 72 3b 0a 20 20 20 20  oot = iPtr;.    
1ad30 6c 73 6d 46 72 65 65 28 70 4d 57 2d 3e 70 44 62  lsmFree(pMW->pDb
1ad40 2d 3e 70 45 6e 76 2c 20 70 4d 57 2d 3e 68 69 65  ->pEnv, pMW->hie
1ad50 72 2e 61 70 48 69 65 72 29 3b 0a 20 20 20 20 70  r.apHier);.    p
1ad60 4d 57 2d 3e 68 69 65 72 2e 61 70 48 69 65 72 20  MW->hier.apHier 
1ad70 3d 20 30 3b 0a 20 20 20 20 70 4d 57 2d 3e 68 69  = 0;.    pMW->hi
1ad80 65 72 2e 6e 48 69 65 72 20 3d 20 30 3b 0a 20 20  er.nHier = 0;.  
1ad90 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
1ada0 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65  }..static int me
1adb0 72 67 65 57 6f 72 6b 65 72 41 64 64 50 61 64 64  rgeWorkerAddPadd
1adc0 69 6e 67 28 0a 20 20 4d 65 72 67 65 57 6f 72 6b  ing(.  MergeWork
1add0 65 72 20 2a 70 4d 57 20 20 20 20 20 20 20 20 20  er *pMW         
1ade0 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65 20         /* Merge 
1adf0 77 6f 72 6b 65 72 20 6f 62 6a 65 63 74 20 2a 2f  worker object */
1ae00 0a 29 7b 0a 20 20 46 69 6c 65 53 79 73 74 65 6d  .){.  FileSystem
1ae10 20 2a 70 46 53 20 3d 20 70 4d 57 2d 3e 70 44 62   *pFS = pMW->pDb
1ae20 2d 3e 70 46 53 3b 0a 20 20 72 65 74 75 72 6e 20  ->pFS;.  return 
1ae30 6c 73 6d 46 73 53 6f 72 74 65 64 50 61 64 64 69  lsmFsSortedPaddi
1ae40 6e 67 28 70 46 53 2c 20 70 4d 57 2d 3e 70 44 62  ng(pFS, pMW->pDb
1ae50 2d 3e 70 57 6f 72 6b 65 72 2c 20 26 70 4d 57 2d  ->pWorker, &pMW-
1ae60 3e 70 4c 65 76 65 6c 2d 3e 6c 68 73 29 3b 0a 7d  >pLevel->lhs);.}
1ae70 0a 0a 2f 2a 0a 2a 2a 20 52 65 6c 65 61 73 65 20  ../*.** Release 
1ae80 61 6c 6c 20 70 61 67 65 20 72 65 66 65 72 65 6e  all page referen
1ae90 63 65 73 20 63 75 72 72 65 6e 74 6c 79 20 68 65  ces currently he
1aea0 6c 64 20 62 79 20 74 68 65 20 6d 65 72 67 65 2d  ld by the merge-
1aeb0 77 6f 72 6b 65 72 20 70 61 73 73 65 64 0a 2a 2a  worker passed.**
1aec0 20 61 73 20 74 68 65 20 6f 6e 6c 79 20 61 72 67   as the only arg
1aed0 75 6d 65 6e 74 2e 20 55 6e 6c 65 73 73 20 61 6e  ument. Unless an
1aee0 20 65 72 72 6f 72 20 68 61 73 20 6f 63 63 75 72   error has occur
1aef0 72 65 64 2c 20 61 6c 6c 20 70 61 67 65 73 20 68  red, all pages h
1af00 61 76 65 0a 2a 2a 20 61 6c 72 65 61 64 79 20 62  ave.** already b
1af10 65 65 6e 20 72 65 6c 65 61 73 65 64 2e 0a 2a 2f  een released..*/
1af20 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 65 72  .static void mer
1af30 67 65 57 6f 72 6b 65 72 52 65 6c 65 61 73 65 41  geWorkerReleaseA
1af40 6c 6c 28 4d 65 72 67 65 57 6f 72 6b 65 72 20 2a  ll(MergeWorker *
1af50 70 4d 57 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  pMW){.  int i;. 
1af60 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61 73   lsmFsPageReleas
1af70 65 28 70 4d 57 2d 3e 70 50 61 67 65 29 3b 0a 20  e(pMW->pPage);. 
1af80 20 70 4d 57 2d 3e 70 50 61 67 65 20 3d 20 30 3b   pMW->pPage = 0;
1af90 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70  ..  for(i=0; i<p
1afa0 4d 57 2d 3e 68 69 65 72 2e 6e 48 69 65 72 3b 20  MW->hier.nHier; 
1afb0 69 2b 2b 29 7b 0a 20 20 20 20 6c 73 6d 46 73 50  i++){.    lsmFsP
1afc0 61 67 65 52 65 6c 65 61 73 65 28 70 4d 57 2d 3e  ageRelease(pMW->
1afd0 68 69 65 72 2e 61 70 48 69 65 72 5b 69 5d 29 3b  hier.apHier[i]);
1afe0 0a 20 20 20 20 70 4d 57 2d 3e 68 69 65 72 2e 61  .    pMW->hier.a
1aff0 70 48 69 65 72 5b 69 5d 20 3d 20 30 3b 0a 20 20  pHier[i] = 0;.  
1b000 7d 0a 20 20 6c 73 6d 46 72 65 65 28 70 4d 57 2d  }.  lsmFree(pMW-
1b010 3e 70 44 62 2d 3e 70 45 6e 76 2c 20 70 4d 57 2d  >pDb->pEnv, pMW-
1b020 3e 68 69 65 72 2e 61 70 48 69 65 72 29 3b 0a 20  >hier.apHier);. 
1b030 20 70 4d 57 2d 3e 68 69 65 72 2e 61 70 48 69 65   pMW->hier.apHie
1b040 72 20 3d 20 30 3b 0a 20 20 70 4d 57 2d 3e 68 69  r = 0;.  pMW->hi
1b050 65 72 2e 6e 48 69 65 72 20 3d 20 30 3b 0a 7d 0a  er.nHier = 0;.}.
1b060 0a 73 74 61 74 69 63 20 69 6e 74 20 6b 65 79 73  .static int keys
1b070 7a 54 6f 53 6b 69 70 28 46 69 6c 65 53 79 73 74  zToSkip(FileSyst
1b080 65 6d 20 2a 70 46 53 2c 20 69 6e 74 20 6e 4b 65  em *pFS, int nKe
1b090 79 29 7b 0a 20 20 69 6e 74 20 6e 50 67 73 7a 3b  y){.  int nPgsz;
1b0a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b0b0 2f 2a 20 4e 6f 6d 69 6e 61 6c 20 64 61 74 61 62  /* Nominal datab
1b0c0 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 2a 2f  ase page size */
1b0d0 0a 20 20 6e 50 67 73 7a 20 3d 20 6c 73 6d 46 73  .  nPgsz = lsmFs
1b0e0 50 61 67 65 53 69 7a 65 28 70 46 53 29 3b 0a 20  PageSize(pFS);. 
1b0f0 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4d 49 4e 28   return LSM_MIN(
1b100 28 28 6e 4b 65 79 20 2a 20 34 29 20 2f 20 6e 50  ((nKey * 4) / nP
1b110 67 73 7a 29 2c 20 33 29 3b 0a 7d 0a 0a 2f 2a 0a  gsz), 3);.}../*.
1b120 2a 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20 72  ** Release the r
1b130 65 66 65 72 65 6e 63 65 20 74 6f 20 74 68 65 20  eference to the 
1b140 63 75 72 72 65 6e 74 20 6f 75 74 70 75 74 20 70  current output p
1b150 61 67 65 20 6f 66 20 6d 65 72 67 65 2d 77 6f 72  age of merge-wor
1b160 6b 65 72 20 2a 70 4d 57 0a 2a 2a 20 28 72 65 66  ker *pMW.** (ref
1b170 65 72 65 6e 63 65 20 70 4d 57 2d 3e 70 50 61 67  erence pMW->pPag
1b180 65 29 2e 20 53 65 74 20 74 68 65 20 70 61 67 65  e). Set the page
1b190 20 6e 75 6d 62 65 72 20 76 61 6c 75 65 73 20 69   number values i
1b1a0 6e 20 61 53 61 76 65 5b 5d 20 61 73 20 0a 2a 2a  n aSave[] as .**
1b1b0 20 72 65 71 75 69 72 65 64 20 28 73 65 65 20 63   required (see c
1b1c0 6f 6d 6d 65 6e 74 73 20 61 62 6f 76 65 20 73 74  omments above st
1b1d0 72 75 63 74 20 4d 65 72 67 65 57 6f 72 6b 65 72  ruct MergeWorker
1b1e0 20 66 6f 72 20 64 65 74 61 69 6c 73 29 2e 0a 2a   for details)..*
1b1f0 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 72  /.static int mer
1b200 67 65 57 6f 72 6b 65 72 50 65 72 73 69 73 74 41  geWorkerPersistA
1b210 6e 64 52 65 6c 65 61 73 65 28 4d 65 72 67 65 57  ndRelease(MergeW
1b220 6f 72 6b 65 72 20 2a 70 4d 57 29 7b 0a 20 20 69  orker *pMW){.  i
1b230 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b 0a  nt rc;.  int i;.
1b240 0a 20 20 61 73 73 65 72 74 28 20 70 4d 57 2d 3e  .  assert( pMW->
1b250 70 50 61 67 65 20 7c 7c 20 28 70 4d 57 2d 3e 61  pPage || (pMW->a
1b260 53 61 76 65 5b 30 5d 2e 62 53 74 6f 72 65 3d 3d  Save[0].bStore==
1b270 30 20 26 26 20 70 4d 57 2d 3e 61 53 61 76 65 5b  0 && pMW->aSave[
1b280 31 5d 2e 62 53 74 6f 72 65 3d 3d 30 29 20 29 3b  1].bStore==0) );
1b290 0a 0a 20 20 2f 2a 20 50 65 72 73 69 73 74 20 74  ..  /* Persist t
1b2a0 68 65 20 70 61 67 65 20 2a 2f 0a 20 20 72 63 20  he page */.  rc 
1b2b0 3d 20 6c 73 6d 46 73 50 61 67 65 50 65 72 73 69  = lsmFsPagePersi
1b2c0 73 74 28 70 4d 57 2d 3e 70 50 61 67 65 29 3b 0a  st(pMW->pPage);.
1b2d0 0a 20 20 2f 2a 20 49 66 20 72 65 71 75 69 72 65  .  /* If require
1b2e0 64 2c 20 73 61 76 65 20 74 68 65 20 70 61 67 65  d, save the page
1b2f0 20 6e 75 6d 62 65 72 2e 20 2a 2f 0a 20 20 66 6f   number. */.  fo
1b300 72 28 69 3d 30 3b 20 69 3c 32 3b 20 69 2b 2b 29  r(i=0; i<2; i++)
1b310 7b 0a 20 20 20 20 69 66 28 20 70 4d 57 2d 3e 61  {.    if( pMW->a
1b320 53 61 76 65 5b 69 5d 2e 62 53 74 6f 72 65 20 29  Save[i].bStore )
1b330 7b 0a 20 20 20 20 20 20 70 4d 57 2d 3e 61 53 61  {.      pMW->aSa
1b340 76 65 5b 69 5d 2e 69 50 67 6e 6f 20 3d 20 6c 73  ve[i].iPgno = ls
1b350 6d 46 73 50 61 67 65 4e 75 6d 62 65 72 28 70 4d  mFsPageNumber(pM
1b360 57 2d 3e 70 50 61 67 65 29 3b 0a 20 20 20 20 20  W->pPage);.     
1b370 20 70 4d 57 2d 3e 61 53 61 76 65 5b 69 5d 2e 62   pMW->aSave[i].b
1b380 53 74 6f 72 65 20 3d 20 30 3b 0a 20 20 20 20 7d  Store = 0;.    }
1b390 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 6c 65 61  .  }..  /* Relea
1b3a0 73 65 20 74 68 65 20 63 6f 6d 70 6c 65 74 65 64  se the completed
1b3b0 20 6f 75 74 70 75 74 20 70 61 67 65 2e 20 2a 2f   output page. */
1b3c0 0a 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65  .  lsmFsPageRele
1b3d0 61 73 65 28 70 4d 57 2d 3e 70 50 61 67 65 29 3b  ase(pMW->pPage);
1b3e0 0a 20 20 70 4d 57 2d 3e 70 50 61 67 65 20 3d 20  .  pMW->pPage = 
1b3f0 30 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  0;.  return rc;.
1b400 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65  }../*.** Advance
1b410 20 74 6f 20 74 68 65 20 6e 65 78 74 20 70 61 67   to the next pag
1b420 65 20 6f 66 20 61 6e 20 6f 75 74 70 75 74 20 72  e of an output r
1b430 75 6e 20 62 65 69 6e 67 20 70 6f 70 75 6c 61 74  un being populat
1b440 65 64 20 62 79 20 6d 65 72 67 65 2d 77 6f 72 6b  ed by merge-work
1b450 65 72 0a 2a 2a 20 70 4d 57 2e 20 54 68 65 20 66  er.** pMW. The f
1b460 6f 6f 74 65 72 20 6f 66 20 74 68 65 20 6e 65 77  ooter of the new
1b470 20 70 61 67 65 20 69 73 20 69 6e 69 74 69 61 6c   page is initial
1b480 69 7a 65 64 20 74 6f 20 69 6e 64 69 63 61 74 65  ized to indicate
1b490 20 74 68 61 74 20 69 74 20 63 6f 6e 74 61 69 6e   that it contain
1b4a0 73 0a 2a 2a 20 7a 65 72 6f 20 72 65 63 6f 72 64  s.** zero record
1b4b0 73 2e 20 54 68 65 20 66 6c 61 67 73 20 66 69 65  s. The flags fie
1b4c0 6c 64 20 69 73 20 63 6c 65 61 72 65 64 2e 20 54  ld is cleared. T
1b4d0 68 65 20 70 61 67 65 20 66 6f 6f 74 65 72 20 70  he page footer p
1b4e0 6f 69 6e 74 65 72 20 66 69 65 6c 64 0a 2a 2a 20  ointer field.** 
1b4f0 69 73 20 73 65 74 20 74 6f 20 69 46 50 74 72 2e  is set to iFPtr.
1b500 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73  .**.** If succes
1b510 73 66 75 6c 2c 20 4c 53 4d 5f 4f 4b 20 69 73 20  sful, LSM_OK is 
1b520 72 65 74 75 72 6e 65 64 2e 20 4f 74 68 65 72 77  returned. Otherw
1b530 69 73 65 2c 20 61 6e 20 65 72 72 6f 72 20 63 6f  ise, an error co
1b540 64 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  de..*/.static in
1b550 74 20 6d 65 72 67 65 57 6f 72 6b 65 72 4e 65 78  t mergeWorkerNex
1b560 74 50 61 67 65 28 0a 20 20 4d 65 72 67 65 57 6f  tPage(.  MergeWo
1b570 72 6b 65 72 20 2a 70 4d 57 2c 20 20 20 20 20 20  rker *pMW,      
1b580 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 72 67           /* Merg
1b590 65 20 77 6f 72 6b 65 72 20 6f 62 6a 65 63 74 20  e worker object 
1b5a0 74 6f 20 61 70 70 65 6e 64 20 70 61 67 65 20 74  to append page t
1b5b0 6f 20 2a 2f 0a 20 20 4c 73 6d 50 67 6e 6f 20 69  o */.  LsmPgno i
1b5c0 46 50 74 72 20 20 20 20 20 20 20 20 20 20 20 20  FPtr            
1b5d0 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
1b5e0 72 20 76 61 6c 75 65 20 66 6f 72 20 66 6f 6f 74  r value for foot
1b5f0 65 72 20 6f 66 20 6e 65 77 20 70 61 67 65 20 2a  er of new page *
1b600 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  /.){.  int rc = 
1b610 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  LSM_OK;         
1b620 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
1b630 20 63 6f 64 65 20 2a 2f 0a 20 20 50 61 67 65 20   code */.  Page 
1b640 2a 70 4e 65 78 74 20 3d 20 30 3b 20 20 20 20 20  *pNext = 0;     
1b650 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65             /* Ne
1b660 77 20 70 61 67 65 20 61 70 70 65 6e 64 65 64 20  w page appended 
1b670 74 6f 20 72 75 6e 20 2a 2f 0a 20 20 6c 73 6d 5f  to run */.  lsm_
1b680 64 62 20 2a 70 44 62 20 3d 20 70 4d 57 2d 3e 70  db *pDb = pMW->p
1b690 44 62 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 44  Db;         /* D
1b6a0 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a  atabase handle *
1b6b0 2f 0a 0a 20 20 72 63 20 3d 20 6c 73 6d 46 73 53  /..  rc = lsmFsS
1b6c0 6f 72 74 65 64 41 70 70 65 6e 64 28 70 44 62 2d  ortedAppend(pDb-
1b6d0 3e 70 46 53 2c 20 70 44 62 2d 3e 70 57 6f 72 6b  >pFS, pDb->pWork
1b6e0 65 72 2c 20 70 4d 57 2d 3e 70 4c 65 76 65 6c 2c  er, pMW->pLevel,
1b6f0 20 30 2c 20 26 70 4e 65 78 74 29 3b 0a 20 20 61   0, &pNext);.  a
1b700 73 73 65 72 74 28 20 72 63 20 7c 7c 20 70 4d 57  ssert( rc || pMW
1b710 2d 3e 70 4c 65 76 65 6c 2d 3e 6c 68 73 2e 69 46  ->pLevel->lhs.iF
1b720 69 72 73 74 3e 30 20 7c 7c 20 70 4d 57 2d 3e 70  irst>0 || pMW->p
1b730 44 62 2d 3e 63 6f 6d 70 72 65 73 73 2e 78 43 6f  Db->compress.xCo
1b740 6d 70 72 65 73 73 20 29 3b 0a 0a 20 20 69 66 28  mpress );..  if(
1b750 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20   rc==LSM_OK ){. 
1b760 20 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20 20     u8 *aData;   
1b770 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b780 20 2f 2a 20 44 61 74 61 20 62 75 66 66 65 72 20   /* Data buffer 
1b790 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 70 61 67  belonging to pag
1b7a0 65 20 70 4e 65 78 74 20 2a 2f 0a 20 20 20 20 69  e pNext */.    i
1b7b0 6e 74 20 6e 44 61 74 61 3b 20 20 20 20 20 20 20  nt nData;       
1b7c0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1b7d0 53 69 7a 65 20 6f 66 20 61 44 61 74 61 5b 5d 20  Size of aData[] 
1b7e0 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 20 20 20  in bytes */..   
1b7f0 20 72 63 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65   rc = mergeWorke
1b800 72 50 65 72 73 69 73 74 41 6e 64 52 65 6c 65 61  rPersistAndRelea
1b810 73 65 28 70 4d 57 29 3b 0a 0a 20 20 20 20 70 4d  se(pMW);..    pM
1b820 57 2d 3e 70 50 61 67 65 20 3d 20 70 4e 65 78 74  W->pPage = pNext
1b830 3b 0a 20 20 20 20 70 4d 57 2d 3e 70 4c 65 76 65  ;.    pMW->pLeve
1b840 6c 2d 3e 70 4d 65 72 67 65 2d 3e 69 4f 75 74 70  l->pMerge->iOutp
1b850 75 74 4f 66 66 20 3d 20 30 3b 0a 20 20 20 20 61  utOff = 0;.    a
1b860 44 61 74 61 20 3d 20 66 73 50 61 67 65 44 61 74  Data = fsPageDat
1b870 61 28 70 4e 65 78 74 2c 20 26 6e 44 61 74 61 29  a(pNext, &nData)
1b880 3b 0a 20 20 20 20 6c 73 6d 50 75 74 55 31 36 28  ;.    lsmPutU16(
1b890 26 61 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f 4e  &aData[SEGMENT_N
1b8a0 52 45 43 4f 52 44 5f 4f 46 46 53 45 54 28 6e 44  RECORD_OFFSET(nD
1b8b0 61 74 61 29 5d 2c 20 30 29 3b 0a 20 20 20 20 6c  ata)], 0);.    l
1b8c0 73 6d 50 75 74 55 31 36 28 26 61 44 61 74 61 5b  smPutU16(&aData[
1b8d0 53 45 47 4d 45 4e 54 5f 46 4c 41 47 53 5f 4f 46  SEGMENT_FLAGS_OF
1b8e0 46 53 45 54 28 6e 44 61 74 61 29 5d 2c 20 30 29  FSET(nData)], 0)
1b8f0 3b 0a 20 20 20 20 6c 73 6d 50 75 74 55 36 34 28  ;.    lsmPutU64(
1b900 26 61 44 61 74 61 5b 53 45 47 4d 45 4e 54 5f 50  &aData[SEGMENT_P
1b910 4f 49 4e 54 45 52 5f 4f 46 46 53 45 54 28 6e 44  OINTER_OFFSET(nD
1b920 61 74 61 29 5d 2c 20 69 46 50 74 72 29 3b 0a 20  ata)], iFPtr);. 
1b930 20 20 20 70 4d 57 2d 3e 6e 57 6f 72 6b 2b 2b 3b     pMW->nWork++;
1b940 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
1b950 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74  c;.}../*.** Writ
1b960 65 20 61 20 62 6c 6f 62 20 6f 66 20 64 61 74 61  e a blob of data
1b970 20 69 6e 74 6f 20 61 6e 20 6f 75 74 70 75 74 20   into an output 
1b980 73 65 67 6d 65 6e 74 20 62 65 69 6e 67 20 70 6f  segment being po
1b990 70 75 6c 61 74 65 64 20 62 79 20 61 20 0a 2a 2a  pulated by a .**
1b9a0 20 6d 65 72 67 65 2d 77 6f 72 6b 65 72 20 6f 62   merge-worker ob
1b9b0 6a 65 63 74 2e 20 49 66 20 61 72 67 75 6d 65 6e  ject. If argumen
1b9c0 74 20 62 53 65 70 20 69 73 20 74 72 75 65 2c 20  t bSep is true, 
1b9d0 77 72 69 74 65 20 69 6e 74 6f 20 74 68 65 20 73  write into the s
1b9e0 65 70 61 72 61 74 6f 72 73 0a 2a 2a 20 61 72 72  eparators.** arr
1b9f0 61 79 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 74  ay. Otherwise, t
1ba00 68 65 20 6d 61 69 6e 20 61 72 72 61 79 2e 0a 2a  he main array..*
1ba10 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
1ba20 6f 6e 20 69 73 20 75 73 65 64 20 74 6f 20 77 72  on is used to wr
1ba30 69 74 65 20 74 68 65 20 62 6c 6f 62 73 20 6f 66  ite the blobs of
1ba40 20 64 61 74 61 20 66 6f 72 20 6b 65 79 73 20 61   data for keys a
1ba50 6e 64 20 76 61 6c 75 65 73 2e 0a 2a 2f 0a 73 74  nd values..*/.st
1ba60 61 74 69 63 20 69 6e 74 20 6d 65 72 67 65 57 6f  atic int mergeWo
1ba70 72 6b 65 72 44 61 74 61 28 0a 20 20 4d 65 72 67  rkerData(.  Merg
1ba80 65 57 6f 72 6b 65 72 20 2a 70 4d 57 2c 20 20 20  eWorker *pMW,   
1ba90 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
1baa0 65 72 67 65 20 77 6f 72 6b 65 72 20 6f 62 6a 65  erge worker obje
1bab0 63 74 20 2a 2f 0a 20 20 69 6e 74 20 62 53 65 70  ct */.  int bSep
1bac0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1bad0 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
1bae0 74 6f 20 77 72 69 74 65 20 74 6f 20 73 65 70 61  to write to sepa
1baf0 72 61 74 6f 72 73 20 72 75 6e 20 2a 2f 0a 20 20  rators run */.  
1bb00 69 6e 74 20 69 46 50 74 72 2c 20 20 20 20 20 20  int iFPtr,      
1bb10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bb20 2f 2a 20 46 6f 6f 74 65 72 20 70 74 72 20 66 6f  /* Footer ptr fo
1bb30 72 20 6e 65 77 20 70 61 67 65 73 20 2a 2f 0a 20  r new pages */. 
1bb40 20 75 38 20 2a 61 57 72 69 74 65 2c 20 20 20 20   u8 *aWrite,    
1bb50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bb60 20 2f 2a 20 57 72 69 74 65 20 64 61 74 61 20 66   /* Write data f
1bb70 72 6f 6d 20 74 68 69 73 20 62 75 66 66 65 72 20  rom this buffer 
1bb80 2a 2f 0a 20 20 69 6e 74 20 6e 57 72 69 74 65 20  */.  int nWrite 
1bb90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bba0 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
1bbb0 61 57 72 69 74 65 5b 5d 20 69 6e 20 62 79 74 65  aWrite[] in byte
1bbc0 73 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  s */.){.  int rc
1bbd0 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20   = LSM_OK;      
1bbe0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
1bbf0 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e  urn code */.  in
1bc00 74 20 6e 52 65 6d 20 3d 20 6e 57 72 69 74 65 3b  t nRem = nWrite;
1bc10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1bc20 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   Number of bytes
1bc30 20 73 74 69 6c 6c 20 74 6f 20 77 72 69 74 65 20   still to write 
1bc40 2a 2f 0a 0a 20 20 77 68 69 6c 65 28 20 72 63 3d  */..  while( rc=
1bc50 3d 4c 53 4d 5f 4f 4b 20 26 26 20 6e 52 65 6d 3e  =LSM_OK && nRem>
1bc60 30 20 29 7b 0a 20 20 20 20 4d 65 72 67 65 20 2a  0 ){.    Merge *
1bc70 70 4d 65 72 67 65 20 3d 20 70 4d 57 2d 3e 70 4c  pMerge = pMW->pL
1bc80 65 76 65 6c 2d 3e 70 4d 65 72 67 65 3b 0a 20 20  evel->pMerge;.  
1bc90 20 20 69 6e 74 20 6e 43 6f 70 79 3b 20 20 20 20    int nCopy;    
1bca0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bcb0 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74  /* Number of byt
1bcc0 65 73 20 74 6f 20 63 6f 70 79 20 2a 2f 0a 20 20  es to copy */.  
1bcd0 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20 20 20    u8 *aData;    
1bce0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bcf0 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62 75  /* Pointer to bu
1bd00 66 66 65 72 20 6f 66 20 63 75 72 72 65 6e 74 20  ffer of current 
1bd10 6f 75 74 70 75 74 20 70 61 67 65 20 2a 2f 0a 20  output page */. 
1bd20 20 20 20 69 6e 74 20 6e 44 61 74 61 3b 20 20 20     int nData;   
1bd30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bd40 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 44 61 74   /* Size of aDat
1bd50 61 5b 5d 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  a[] in bytes */.
1bd60 20 20 20 20 69 6e 74 20 6e 52 65 63 3b 20 20 20      int nRec;   
1bd70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bd80 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 72    /* Number of r
1bd90 65 63 6f 72 64 73 20 6f 6e 20 63 75 72 72 65 6e  ecords on curren
1bda0 74 20 6f 75 74 70 75 74 20 70 61 67 65 20 2a 2f  t output page */
1bdb0 0a 20 20 20 20 69 6e 74 20 69 4f 66 66 3b 20 20  .    int iOff;  
1bdc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bdd0 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 69 6e 20     /* Offset in 
1bde0 61 44 61 74 61 5b 5d 20 74 6f 20 77 72 69 74 65  aData[] to write
1bdf0 20 74 6f 20 2a 2f 0a 0a 20 20 20 20 61 73 73 65   to */..    asse
1be00 72 74 28 20 6c 73 6d 46 73 50 61 67 65 57 72 69  rt( lsmFsPageWri
1be10 74 61 62 6c 65 28 70 4d 57 2d 3e 70 50 61 67 65  table(pMW->pPage
1be20 29 20 29 3b 0a 20 20 20 0a 20 20 20 20 61 44 61  ) );.   .    aDa
1be30 74 61 20 3d 20 66 73 50 61 67 65 44 61 74 61 28  ta = fsPageData(
1be40 70 4d 57 2d 3e 70 50 61 67 65 2c 20 26 6e 44 61  pMW->pPage, &nDa
1be50 74 61 29 3b 0a 20 20 20 20 6e 52 65 63 20 3d 20  ta);.    nRec = 
1be60 70 61 67 65 47 65 74 4e 52 65 63 28 61 44 61 74  pageGetNRec(aDat
1be70 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 69  a, nData);.    i
1be80 4f 66 66 20 3d 20 70 4d 65 72 67 65 2d 3e 69 4f  Off = pMerge->iO
1be90 75 74 70 75 74 4f 66 66 3b 0a 20 20 20 20 6e 43  utputOff;.    nC
1bea0 6f 70 79 20 3d 20 4c 53 4d 5f 4d 49 4e 28 6e 52  opy = LSM_MIN(nR
1beb0 65 6d 2c 20 53 45 47 4d 45 4e 54 5f 45 4f 46 28  em, SEGMENT_EOF(
1bec0 6e 44 61 74 61 2c 20 6e 52 65 63 29 20 2d 20 69  nData, nRec) - i
1bed0 4f 66 66 29 3b 0a 0a 20 20 20 20 6d 65 6d 63 70  Off);..    memcp
1bee0 79 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c 20  y(&aData[iOff], 
1bef0 26 61 57 72 69 74 65 5b 6e 57 72 69 74 65 2d 6e  &aWrite[nWrite-n
1bf00 52 65 6d 5d 2c 20 6e 43 6f 70 79 29 3b 0a 20 20  Rem], nCopy);.  
1bf10 20 20 6e 52 65 6d 20 2d 3d 20 6e 43 6f 70 79 3b    nRem -= nCopy;
1bf20 0a 0a 20 20 20 20 69 66 28 20 6e 52 65 6d 3e 30  ..    if( nRem>0
1bf30 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 6d   ){.      rc = m
1bf40 65 72 67 65 57 6f 72 6b 65 72 4e 65 78 74 50 61  ergeWorkerNextPa
1bf50 67 65 28 70 4d 57 2c 20 69 46 50 74 72 29 3b 0a  ge(pMW, iFPtr);.
1bf60 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
1bf70 20 70 4d 65 72 67 65 2d 3e 69 4f 75 74 70 75 74   pMerge->iOutput
1bf80 4f 66 66 20 3d 20 69 4f 66 66 20 2b 20 6e 43 6f  Off = iOff + nCo
1bf90 70 79 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  py;.    }.  }.. 
1bfa0 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a   return rc;.}...
1bfb0 2f 2a 0a 2a 2a 20 54 68 65 20 4d 65 72 67 65 57  /*.** The MergeW
1bfc0 6f 72 6b 65 72 20 70 61 73 73 65 64 20 61 73 20  orker passed as 
1bfd0 74 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e  the only argumen
1bfe0 74 20 69 73 20 77 6f 72 6b 69 6e 67 20 74 6f 20  t is working to 
1bff0 6d 65 72 67 65 20 74 77 6f 20 6f 72 0a 2a 2a 20  merge two or.** 
1c000 6d 6f 72 65 20 65 78 69 73 74 69 6e 67 20 73 65  more existing se
1c010 67 6d 65 6e 74 73 20 74 6f 67 65 74 68 65 72 20  gments together 
1c020 28 6e 6f 74 20 74 6f 20 66 6c 75 73 68 20 61 6e  (not to flush an
1c030 20 69 6e 2d 6d 65 6d 6f 72 79 20 74 72 65 65 29   in-memory tree)
1c040 2e 20 49 74 0a 2a 2a 20 68 61 73 20 6e 6f 74 20  . It.** has not 
1c050 79 65 74 20 77 72 69 74 74 65 6e 20 74 68 65 20  yet written the 
1c060 66 69 72 73 74 20 6b 65 79 20 74 6f 20 74 68 65  first key to the
1c070 20 66 69 72 73 74 20 70 61 67 65 20 6f 66 20 74   first page of t
1c080 68 65 20 6f 75 74 70 75 74 2e 0a 2a 2f 0a 73 74  he output..*/.st
1c090 61 74 69 63 20 69 6e 74 20 6d 65 72 67 65 57 6f  atic int mergeWo
1c0a0 72 6b 65 72 46 69 72 73 74 50 61 67 65 28 4d 65  rkerFirstPage(Me
1c0b0 72 67 65 57 6f 72 6b 65 72 20 2a 70 4d 57 29 7b  rgeWorker *pMW){
1c0c0 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f  .  int rc = LSM_
1c0d0 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
1c0e0 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
1c0f0 65 20 2a 2f 0a 20 20 50 61 67 65 20 2a 70 50 67  e */.  Page *pPg
1c100 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
1c110 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20         /* First 
1c120 70 61 67 65 20 6f 66 20 72 75 6e 20 70 53 65 67  page of run pSeg
1c130 20 2a 2f 0a 20 20 69 6e 74 20 69 46 50 74 72 20   */.  int iFPtr 
1c140 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
1c150 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
1c160 20 76 61 6c 75 65 20 72 65 61 64 20 66 72 6f 6d   value read from
1c170 20 66 6f 6f 74 65 72 20 6f 66 20 70 50 67 20 2a   footer of pPg *
1c180 2f 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  /.  MultiCursor 
1c190 2a 70 43 73 72 20 3d 20 70 4d 57 2d 3e 70 43 73  *pCsr = pMW->pCs
1c1a0 72 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 4d  r;..  assert( pM
1c1b0 57 2d 3e 70 50 61 67 65 3d 3d 30 20 29 3b 0a 0a  W->pPage==0 );..
1c1c0 20 20 69 66 28 20 70 43 73 72 2d 3e 70 42 74 43    if( pCsr->pBtC
1c1d0 73 72 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 4c  sr ){.    rc = L
1c1e0 53 4d 5f 4f 4b 3b 0a 20 20 20 20 69 46 50 74 72  SM_OK;.    iFPtr
1c1f0 20 3d 20 28 69 6e 74 29 70 4d 57 2d 3e 70 4c 65   = (int)pMW->pLe
1c200 76 65 6c 2d 3e 70 4e 65 78 74 2d 3e 6c 68 73 2e  vel->pNext->lhs.
1c210 69 46 69 72 73 74 3b 0a 20 20 7d 65 6c 73 65 20  iFirst;.  }else 
1c220 69 66 28 20 70 43 73 72 2d 3e 6e 50 74 72 3e 30  if( pCsr->nPtr>0
1c230 20 29 7b 0a 20 20 20 20 53 65 67 6d 65 6e 74 20   ){.    Segment 
1c240 2a 70 53 65 67 3b 0a 20 20 20 20 70 53 65 67 20  *pSeg;.    pSeg 
1c250 3d 20 70 43 73 72 2d 3e 61 50 74 72 5b 70 43 73  = pCsr->aPtr[pCs
1c260 72 2d 3e 6e 50 74 72 2d 31 5d 2e 70 53 65 67 3b  r->nPtr-1].pSeg;
1c270 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 44  .    rc = lsmFsD
1c280 62 50 61 67 65 47 65 74 28 70 4d 57 2d 3e 70 44  bPageGet(pMW->pD
1c290 62 2d 3e 70 46 53 2c 20 70 53 65 67 2c 20 70 53  b->pFS, pSeg, pS
1c2a0 65 67 2d 3e 69 46 69 72 73 74 2c 20 26 70 50 67  eg->iFirst, &pPg
1c2b0 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  );.    if( rc==L
1c2c0 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 75  SM_OK ){.      u
1c2d0 38 20 2a 61 44 61 74 61 3b 20 20 20 20 20 20 20  8 *aData;       
1c2e0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1c2f0 42 75 66 66 65 72 20 66 6f 72 20 70 61 67 65 20  Buffer for page 
1c300 70 50 67 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  pPg */.      int
1c310 20 6e 44 61 74 61 3b 20 20 20 20 20 20 20 20 20   nData;         
1c320 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
1c330 7a 65 20 6f 66 20 61 44 61 74 61 5b 5d 20 69 6e  ze of aData[] in
1c340 20 62 79 74 65 73 20 2a 2f 0a 20 20 20 20 20 20   bytes */.      
1c350 61 44 61 74 61 20 3d 20 66 73 50 61 67 65 44 61  aData = fsPageDa
1c360 74 61 28 70 50 67 2c 20 26 6e 44 61 74 61 29 3b  ta(pPg, &nData);
1c370 0a 20 20 20 20 20 20 69 46 50 74 72 20 3d 20 28  .      iFPtr = (
1c380 69 6e 74 29 70 61 67 65 47 65 74 50 74 72 28 61  int)pageGetPtr(a
1c390 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20  Data, nData);.  
1c3a0 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c      lsmFsPageRel
1c3b0 65 61 73 65 28 70 50 67 29 3b 0a 20 20 20 20 7d  ease(pPg);.    }
1c3c0 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
1c3d0 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  LSM_OK ){.    rc
1c3e0 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65 72 4e 65   = mergeWorkerNe
1c3f0 78 74 50 61 67 65 28 70 4d 57 2c 20 69 46 50 74  xtPage(pMW, iFPt
1c400 72 29 3b 0a 20 20 20 20 69 66 28 20 70 43 73 72  r);.    if( pCsr
1c410 2d 3e 70 50 72 65 76 4d 65 72 67 65 50 74 72 20  ->pPrevMergePtr 
1c420 29 20 2a 70 43 73 72 2d 3e 70 50 72 65 76 4d 65  ) *pCsr->pPrevMe
1c430 72 67 65 50 74 72 20 3d 20 69 46 50 74 72 3b 0a  rgePtr = iFPtr;.
1c440 20 20 20 20 70 4d 57 2d 3e 61 53 61 76 65 5b 30      pMW->aSave[0
1c450 5d 2e 62 53 74 6f 72 65 20 3d 20 31 3b 0a 20 20  ].bStore = 1;.  
1c460 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
1c470 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65  }..static int me
1c480 72 67 65 57 6f 72 6b 65 72 57 72 69 74 65 28 0a  rgeWorkerWrite(.
1c490 20 20 4d 65 72 67 65 57 6f 72 6b 65 72 20 2a 70    MergeWorker *p
1c4a0 4d 57 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  MW,             
1c4b0 20 20 2f 2a 20 4d 65 72 67 65 20 77 6f 72 6b 65    /* Merge worke
1c4c0 72 20 6f 62 6a 65 63 74 20 74 6f 20 77 72 69 74  r object to writ
1c4d0 65 20 69 6e 74 6f 20 2a 2f 0a 20 20 69 6e 74 20  e into */.  int 
1c4e0 65 54 79 70 65 2c 20 20 20 20 20 20 20 20 20 20  eType,          
1c4f0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
1c500 6e 65 20 6f 66 20 53 4f 52 54 45 44 5f 53 45 50  ne of SORTED_SEP
1c510 41 52 41 54 4f 52 2c 20 57 52 49 54 45 20 6f 72  ARATOR, WRITE or
1c520 20 44 45 4c 45 54 45 20 2a 2f 0a 20 20 76 6f 69   DELETE */.  voi
1c530 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b 65  d *pKey, int nKe
1c540 79 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  y,           /* 
1c550 4b 65 79 20 76 61 6c 75 65 20 2a 2f 0a 20 20 76  Key value */.  v
1c560 6f 69 64 20 2a 70 56 61 6c 2c 20 69 6e 74 20 6e  oid *pVal, int n
1c570 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 2f  Val,           /
1c580 2a 20 56 61 6c 75 65 20 76 61 6c 75 65 20 2a 2f  * Value value */
1c590 0a 20 20 69 6e 74 20 69 50 74 72 20 20 20 20 20  .  int iPtr     
1c5a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c5b0 20 20 20 2f 2a 20 41 62 73 6f 6c 75 74 65 20 76     /* Absolute v
1c5c0 61 6c 75 65 20 6f 66 20 70 61 67 65 20 70 6f 69  alue of page poi
1c5d0 6e 74 65 72 2c 20 6f 72 20 30 20 2a 2f 0a 29 7b  nter, or 0 */.){
1c5e0 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f  .  int rc = LSM_
1c5f0 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
1c600 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
1c610 65 20 2a 2f 0a 20 20 4d 65 72 67 65 20 2a 70 4d  e */.  Merge *pM
1c620 65 72 67 65 3b 20 20 20 20 20 20 20 20 20 20 20  erge;           
1c630 20 20 20 20 20 20 20 2f 2a 20 50 65 72 73 69 73         /* Persis
1c640 74 65 6e 74 20 70 61 72 74 20 6f 66 20 6c 65 76  tent part of lev
1c650 65 6c 20 6d 65 72 67 65 20 73 74 61 74 65 20 2a  el merge state *
1c660 2f 0a 20 20 69 6e 74 20 6e 48 64 72 3b 20 20 20  /.  int nHdr;   
1c670 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c680 20 20 20 20 2f 2a 20 53 70 61 63 65 20 72 65 71      /* Space req
1c690 75 69 72 65 64 20 66 6f 72 20 74 68 69 73 20 72  uired for this r
1c6a0 65 63 6f 72 64 20 68 65 61 64 65 72 20 2a 2f 0a  ecord header */.
1c6b0 20 20 50 61 67 65 20 2a 70 50 67 3b 20 20 20 20    Page *pPg;    
1c6c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c6d0 20 20 2f 2a 20 50 61 67 65 20 74 6f 20 77 72 69    /* Page to wri
1c6e0 74 65 20 74 6f 20 2a 2f 0a 20 20 75 38 20 2a 61  te to */.  u8 *a
1c6f0 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20  Data;           
1c700 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
1c710 74 61 20 62 75 66 66 65 72 20 66 6f 72 20 70 61  ta buffer for pa
1c720 67 65 20 70 57 72 69 74 65 72 2d 3e 70 50 61 67  ge pWriter->pPag
1c730 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 44 61 74 61  e */.  int nData
1c740 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
1c750 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
1c760 66 20 62 75 66 66 65 72 20 61 44 61 74 61 5b 5d  f buffer aData[]
1c770 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69   in bytes */.  i
1c780 6e 74 20 6e 52 65 63 20 3d 20 30 3b 20 20 20 20  nt nRec = 0;    
1c790 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1c7a0 2a 20 4e 75 6d 62 65 72 20 6f 66 20 72 65 63 6f  * Number of reco
1c7b0 72 64 73 20 6f 6e 20 70 61 67 65 20 70 50 67 20  rds on page pPg 
1c7c0 2a 2f 0a 20 20 69 6e 74 20 69 46 50 74 72 20 3d  */.  int iFPtr =
1c7d0 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
1c7e0 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f 66       /* Value of
1c7f0 20 70 6f 69 6e 74 65 72 20 69 6e 20 66 6f 6f 74   pointer in foot
1c800 65 72 20 6f 66 20 70 50 67 20 2a 2f 0a 20 20 69  er of pPg */.  i
1c810 6e 74 20 69 52 50 74 72 20 3d 20 30 3b 20 20 20  nt iRPtr = 0;   
1c820 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1c830 2a 20 56 61 6c 75 65 20 6f 66 20 70 6f 69 6e 74  * Value of point
1c840 65 72 20 77 72 69 74 74 65 6e 20 69 6e 74 6f 20  er written into 
1c850 72 65 63 6f 72 64 20 2a 2f 0a 20 20 69 6e 74 20  record */.  int 
1c860 69 4f 66 66 20 3d 20 30 3b 20 20 20 20 20 20 20  iOff = 0;       
1c870 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
1c880 75 72 72 65 6e 74 20 77 72 69 74 65 20 6f 66 66  urrent write off
1c890 73 65 74 20 77 69 74 68 69 6e 20 70 61 67 65 20  set within page 
1c8a0 70 50 67 20 2a 2f 0a 20 20 53 65 67 6d 65 6e 74  pPg */.  Segment
1c8b0 20 2a 70 53 65 67 3b 20 20 20 20 20 20 20 20 20   *pSeg;         
1c8c0 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 67 6d           /* Segm
1c8d0 65 6e 74 20 62 65 69 6e 67 20 77 72 69 74 74 65  ent being writte
1c8e0 6e 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73  n */.  int flags
1c8f0 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
1c900 20 20 20 20 20 20 20 2f 2a 20 49 66 20 21 3d 20         /* If != 
1c910 30 2c 20 66 6c 61 67 73 20 76 61 6c 75 65 20 66  0, flags value f
1c920 6f 72 20 70 61 67 65 20 66 6f 6f 74 65 72 20 2a  or page footer *
1c930 2f 0a 20 20 69 6e 74 20 62 46 69 72 73 74 20 3d  /.  int bFirst =
1c940 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
1c950 20 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20      /* True for 
1c960 66 69 72 73 74 20 6b 65 79 20 6f 66 20 6f 75 74  first key of out
1c970 70 75 74 20 72 75 6e 20 2a 2f 0a 0a 20 20 70 4d  put run */..  pM
1c980 65 72 67 65 20 3d 20 70 4d 57 2d 3e 70 4c 65 76  erge = pMW->pLev
1c990 65 6c 2d 3e 70 4d 65 72 67 65 3b 20 20 20 20 0a  el->pMerge;    .
1c9a0 20 20 70 53 65 67 20 3d 20 26 70 4d 57 2d 3e 70    pSeg = &pMW->p
1c9b0 4c 65 76 65 6c 2d 3e 6c 68 73 3b 0a 0a 20 20 69  Level->lhs;..  i
1c9c0 66 28 20 70 53 65 67 2d 3e 69 46 69 72 73 74 3d  f( pSeg->iFirst=
1c9d0 3d 30 20 26 26 20 70 4d 57 2d 3e 70 50 61 67 65  =0 && pMW->pPage
1c9e0 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  ==0 ){.    rc = 
1c9f0 6d 65 72 67 65 57 6f 72 6b 65 72 46 69 72 73 74  mergeWorkerFirst
1ca00 50 61 67 65 28 70 4d 57 29 3b 0a 20 20 20 20 62  Page(pMW);.    b
1ca10 46 69 72 73 74 20 3d 20 31 3b 0a 20 20 7d 0a 20  First = 1;.  }. 
1ca20 20 70 50 67 20 3d 20 70 4d 57 2d 3e 70 50 61 67   pPg = pMW->pPag
1ca30 65 3b 0a 20 20 69 66 28 20 70 50 67 20 29 7b 0a  e;.  if( pPg ){.
1ca40 20 20 20 20 61 44 61 74 61 20 3d 20 66 73 50 61      aData = fsPa
1ca50 67 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44 61  geData(pPg, &nDa
1ca60 74 61 29 3b 0a 20 20 20 20 6e 52 65 63 20 3d 20  ta);.    nRec = 
1ca70 70 61 67 65 47 65 74 4e 52 65 63 28 61 44 61 74  pageGetNRec(aDat
1ca80 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 69  a, nData);.    i
1ca90 46 50 74 72 20 3d 20 28 69 6e 74 29 70 61 67 65  FPtr = (int)page
1caa0 47 65 74 50 74 72 28 61 44 61 74 61 2c 20 6e 44  GetPtr(aData, nD
1cab0 61 74 61 29 3b 0a 20 20 20 20 69 52 50 74 72 20  ata);.    iRPtr 
1cac0 3d 20 69 50 74 72 20 2d 20 69 46 50 74 72 3b 0a  = iPtr - iFPtr;.
1cad0 20 20 7d 0a 20 20 20 20 20 0a 20 20 2f 2a 20 46    }.     .  /* F
1cae0 69 67 75 72 65 20 6f 75 74 20 68 6f 77 20 6d 75  igure out how mu
1caf0 63 68 20 73 70 61 63 65 20 69 73 20 72 65 71 75  ch space is requ
1cb00 69 72 65 64 20 62 79 20 74 68 65 20 6e 65 77 20  ired by the new 
1cb10 72 65 63 6f 72 64 2e 20 54 68 65 20 73 70 61 63  record. The spac
1cb20 65 0a 20 20 2a 2a 20 72 65 71 75 69 72 65 64 20  e.  ** required 
1cb30 69 73 20 64 69 76 69 64 65 64 20 69 6e 74 6f 20  is divided into 
1cb40 74 77 6f 20 73 65 63 74 69 6f 6e 73 3a 20 74 68  two sections: th
1cb50 65 20 68 65 61 64 65 72 20 61 6e 64 20 74 68 65  e header and the
1cb60 20 62 6f 64 79 2e 20 54 68 65 0a 20 20 2a 2a 20   body. The.  ** 
1cb70 68 65 61 64 65 72 20 63 6f 6e 73 69 73 74 73 20  header consists 
1cb80 6f 66 20 74 68 65 20 69 6e 74 69 61 6c 20 76 61  of the intial va
1cb90 72 69 6e 74 20 66 69 65 6c 64 73 2e 20 54 68 65  rint fields. The
1cba0 20 62 6f 64 79 20 61 72 65 20 74 68 65 20 62 6c   body are the bl
1cbb0 6f 62 73 20 0a 20 20 2a 2a 20 6f 66 20 64 61 74  obs .  ** of dat
1cbc0 61 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e  a that correspon
1cbd0 64 20 74 6f 20 74 68 65 20 6b 65 79 20 61 6e 64  d to the key and
1cbe0 20 76 61 6c 75 65 20 64 61 74 61 2e 20 54 68 65   value data. The
1cbf0 20 65 6e 74 69 72 65 20 68 65 61 64 65 72 20 0a   entire header .
1cc00 20 20 2a 2a 20 6d 75 73 74 20 62 65 20 73 74 6f    ** must be sto
1cc10 72 65 64 20 6f 6e 20 74 68 65 20 70 61 67 65 2e  red on the page.
1cc20 20 54 68 65 20 62 6f 64 79 20 6d 61 79 20 6f 76   The body may ov
1cc30 65 72 66 6c 6f 77 20 6f 6e 74 6f 20 74 68 65 20  erflow onto the 
1cc40 6e 65 78 74 20 61 6e 64 0a 20 20 2a 2a 20 73 75  next and.  ** su
1cc50 62 73 65 71 75 65 6e 74 20 70 61 67 65 73 2e 0a  bsequent pages..
1cc60 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 65 20 68 65    **.  ** The he
1cc70 61 64 65 72 20 73 70 61 63 65 20 69 73 3a 0a 20  ader space is:. 
1cc80 20 2a 2a 0a 20 20 2a 2a 20 20 20 20 20 31 29 20   **.  **     1) 
1cc90 72 65 63 6f 72 64 20 74 79 70 65 20 2d 20 31 20  record type - 1 
1cca0 62 79 74 65 2e 0a 20 20 2a 2a 20 20 20 20 20 32  byte..  **     2
1ccb0 29 20 50 61 67 65 2d 70 6f 69 6e 74 65 72 2d 6f  ) Page-pointer-o
1ccc0 66 66 73 65 74 20 2d 20 31 20 76 61 72 69 6e 74  ffset - 1 varint
1ccd0 0a 20 20 2a 2a 20 20 20 20 20 33 29 20 4b 65 79  .  **     3) Key
1cce0 20 73 69 7a 65 20 2d 20 31 20 76 61 72 69 6e 74   size - 1 varint
1ccf0 0a 20 20 2a 2a 20 20 20 20 20 34 29 20 56 61 6c  .  **     4) Val
1cd00 75 65 20 73 69 7a 65 20 2d 20 31 20 76 61 72 69  ue size - 1 vari
1cd10 6e 74 20 28 6f 6e 6c 79 20 69 66 20 4c 53 4d 5f  nt (only if LSM_
1cd20 49 4e 53 45 52 54 20 66 6c 61 67 20 69 73 20 73  INSERT flag is s
1cd30 65 74 29 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72  et).  */.  if( r
1cd40 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
1cd50 20 6e 48 64 72 20 3d 20 31 20 2b 20 6c 73 6d 56   nHdr = 1 + lsmV
1cd60 61 72 69 6e 74 4c 65 6e 33 32 28 69 52 50 74 72  arintLen32(iRPtr
1cd70 29 20 2b 20 6c 73 6d 56 61 72 69 6e 74 4c 65 6e  ) + lsmVarintLen
1cd80 33 32 28 6e 4b 65 79 29 3b 0a 20 20 20 20 69 66  32(nKey);.    if
1cd90 28 20 72 74 49 73 57 72 69 74 65 28 65 54 79 70  ( rtIsWrite(eTyp
1cda0 65 29 20 29 20 6e 48 64 72 20 2b 3d 20 6c 73 6d  e) ) nHdr += lsm
1cdb0 56 61 72 69 6e 74 4c 65 6e 33 32 28 6e 56 61 6c  VarintLen32(nVal
1cdc0 29 3b 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68  );..    /* If th
1cdd0 65 20 65 6e 74 69 72 65 20 68 65 61 64 65 72 20  e entire header 
1cde0 77 69 6c 6c 20 6e 6f 74 20 66 69 74 20 6f 6e 20  will not fit on 
1cdf0 70 61 67 65 20 70 50 67 2c 20 6f 72 20 69 66 20  page pPg, or if 
1ce00 70 61 67 65 20 70 50 67 20 69 73 20 0a 20 20 20  page pPg is .   
1ce10 20 2a 2a 20 6d 61 72 6b 65 64 20 72 65 61 64 2d   ** marked read-
1ce20 6f 6e 6c 79 2c 20 61 64 76 61 6e 63 65 20 74 6f  only, advance to
1ce30 20 74 68 65 20 6e 65 78 74 20 70 61 67 65 20 6f   the next page o
1ce40 66 20 74 68 65 20 6f 75 74 70 75 74 20 72 75 6e  f the output run
1ce50 2e 20 2a 2f 0a 20 20 20 20 69 4f 66 66 20 3d 20  . */.    iOff = 
1ce60 70 4d 65 72 67 65 2d 3e 69 4f 75 74 70 75 74 4f  pMerge->iOutputO
1ce70 66 66 3b 0a 20 20 20 20 69 66 28 20 69 4f 66 66  ff;.    if( iOff
1ce80 3c 30 20 7c 7c 20 70 50 67 3d 3d 30 20 7c 7c 20  <0 || pPg==0 || 
1ce90 69 4f 66 66 2b 6e 48 64 72 20 3e 20 53 45 47 4d  iOff+nHdr > SEGM
1cea0 45 4e 54 5f 45 4f 46 28 6e 44 61 74 61 2c 20 6e  ENT_EOF(nData, n
1ceb0 52 65 63 2b 31 29 20 29 7b 0a 20 20 20 20 20 20  Rec+1) ){.      
1cec0 69 66 28 20 69 4f 66 66 3e 3d 30 20 26 26 20 70  if( iOff>=0 && p
1ced0 50 67 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a  Pg ){.        /*
1cee0 20 5a 65 72 6f 20 61 6e 79 20 66 72 65 65 20 73   Zero any free s
1cef0 70 61 63 65 20 6f 6e 20 74 68 65 20 70 61 67 65  pace on the page
1cf00 20 2a 2f 0a 20 20 20 20 20 20 20 20 61 73 73 65   */.        asse
1cf10 72 74 28 20 61 44 61 74 61 20 29 3b 0a 20 20 20  rt( aData );.   
1cf20 20 20 20 20 20 6d 65 6d 73 65 74 28 26 61 44 61       memset(&aDa
1cf30 74 61 5b 69 4f 66 66 5d 2c 20 30 2c 20 53 45 47  ta[iOff], 0, SEG
1cf40 4d 45 4e 54 5f 45 4f 46 28 6e 44 61 74 61 2c 20  MENT_EOF(nData, 
1cf50 6e 52 65 63 29 2d 69 4f 66 66 29 3b 0a 20 20 20  nRec)-iOff);.   
1cf60 20 20 20 7d 0a 20 20 20 20 20 20 69 46 50 74 72     }.      iFPtr
1cf70 20 3d 20 28 69 6e 74 29 2a 70 4d 57 2d 3e 70 43   = (int)*pMW->pC
1cf80 73 72 2d 3e 70 50 72 65 76 4d 65 72 67 65 50 74  sr->pPrevMergePt
1cf90 72 3b 0a 20 20 20 20 20 20 69 52 50 74 72 20 3d  r;.      iRPtr =
1cfa0 20 69 50 74 72 20 2d 20 69 46 50 74 72 3b 0a 20   iPtr - iFPtr;. 
1cfb0 20 20 20 20 20 69 4f 66 66 20 3d 20 30 3b 0a 20       iOff = 0;. 
1cfc0 20 20 20 20 20 6e 52 65 63 20 3d 20 30 3b 0a 20       nRec = 0;. 
1cfd0 20 20 20 20 20 72 63 20 3d 20 6d 65 72 67 65 57       rc = mergeW
1cfe0 6f 72 6b 65 72 4e 65 78 74 50 61 67 65 28 70 4d  orkerNextPage(pM
1cff0 57 2c 20 69 46 50 74 72 29 3b 0a 20 20 20 20 20  W, iFPtr);.     
1d000 20 70 50 67 20 3d 20 70 4d 57 2d 3e 70 50 61 67   pPg = pMW->pPag
1d010 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  e;.    }.  }..  
1d020 2f 2a 20 49 66 20 74 68 69 73 20 72 65 63 6f 72  /* If this recor
1d030 64 20 68 65 61 64 65 72 20 77 69 6c 6c 20 62 65  d header will be
1d040 20 74 68 65 20 66 69 72 73 74 20 6f 6e 20 74 68   the first on th
1d050 65 20 70 61 67 65 2c 20 61 6e 64 20 74 68 65 20  e page, and the 
1d060 70 61 67 65 20 69 73 20 0a 20 20 2a 2a 20 6e 6f  page is .  ** no
1d070 74 20 74 68 65 20 76 65 72 79 20 66 69 72 73 74  t the very first
1d080 20 69 6e 20 74 68 65 20 65 6e 74 69 72 65 20 72   in the entire r
1d090 75 6e 2c 20 61 64 64 20 61 20 63 6f 70 79 20 6f  un, add a copy o
1d0a0 66 20 74 68 65 20 6b 65 79 20 74 6f 20 74 68 65  f the key to the
1d0b0 0a 20 20 2a 2a 20 62 2d 74 72 65 65 20 68 69 65  .  ** b-tree hie
1d0c0 72 61 72 63 68 79 2e 0a 20 20 2a 2f 0a 20 20 69  rarchy..  */.  i
1d0d0 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26  f( rc==LSM_OK &&
1d0e0 20 6e 52 65 63 3d 3d 30 20 26 26 20 62 46 69 72   nRec==0 && bFir
1d0f0 73 74 3d 3d 30 20 29 7b 0a 20 20 20 20 61 73 73  st==0 ){.    ass
1d100 65 72 74 28 20 70 4d 65 72 67 65 2d 3e 6e 53 6b  ert( pMerge->nSk
1d110 69 70 3e 3d 30 20 29 3b 0a 0a 20 20 20 20 69 66  ip>=0 );..    if
1d120 28 20 70 4d 65 72 67 65 2d 3e 6e 53 6b 69 70 3d  ( pMerge->nSkip=
1d130 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  =0 ){.      rc =
1d140 20 6d 65 72 67 65 57 6f 72 6b 65 72 50 75 73 68   mergeWorkerPush
1d150 48 69 65 72 61 72 63 68 79 28 70 4d 57 2c 20 72  Hierarchy(pMW, r
1d160 74 54 6f 70 69 63 28 65 54 79 70 65 29 2c 20 70  tTopic(eType), p
1d170 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 20 20 20 20  Key, nKey);.    
1d180 20 20 61 73 73 65 72 74 28 20 70 4d 57 2d 3e 61    assert( pMW->a
1d190 53 61 76 65 5b 30 5d 2e 62 53 74 6f 72 65 3d 3d  Save[0].bStore==
1d1a0 30 20 29 3b 0a 20 20 20 20 20 20 70 4d 57 2d 3e  0 );.      pMW->
1d1b0 61 53 61 76 65 5b 30 5d 2e 62 53 74 6f 72 65 20  aSave[0].bStore 
1d1c0 3d 20 31 3b 0a 20 20 20 20 20 20 70 4d 65 72 67  = 1;.      pMerg
1d1d0 65 2d 3e 6e 53 6b 69 70 20 3d 20 6b 65 79 73 7a  e->nSkip = keysz
1d1e0 54 6f 53 6b 69 70 28 70 4d 57 2d 3e 70 44 62 2d  ToSkip(pMW->pDb-
1d1f0 3e 70 46 53 2c 20 6e 4b 65 79 29 3b 0a 20 20 20  >pFS, nKey);.   
1d200 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 4d   }else{.      pM
1d210 65 72 67 65 2d 3e 6e 53 6b 69 70 2d 2d 3b 0a 20  erge->nSkip--;. 
1d220 20 20 20 20 20 66 6c 61 67 73 20 3d 20 50 47 46       flags = PGF
1d230 54 52 5f 53 4b 49 50 5f 54 48 49 53 5f 46 4c 41  TR_SKIP_THIS_FLA
1d240 47 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66  G;.    }..    if
1d250 28 20 70 4d 65 72 67 65 2d 3e 6e 53 6b 69 70 20  ( pMerge->nSkip 
1d260 29 20 66 6c 61 67 73 20 7c 3d 20 50 47 46 54 52  ) flags |= PGFTR
1d270 5f 53 4b 49 50 5f 4e 45 58 54 5f 46 4c 41 47 3b  _SKIP_NEXT_FLAG;
1d280 0a 20 20 7d 0a 0a 20 20 2f 2a 20 55 70 64 61 74  .  }..  /* Updat
1d290 65 20 74 68 65 20 6f 75 74 70 75 74 20 73 65 67  e the output seg
1d2a0 6d 65 6e 74 20 2a 2f 0a 20 20 69 66 28 20 72 63  ment */.  if( rc
1d2b0 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20  ==LSM_OK ){.    
1d2c0 61 44 61 74 61 20 3d 20 66 73 50 61 67 65 44 61  aData = fsPageDa
1d2d0 74 61 28 70 50 67 2c 20 26 6e 44 61 74 61 29 3b  ta(pPg, &nData);
1d2e0 0a 0a 20 20 20 20 2f 2a 20 55 70 64 61 74 65 20  ..    /* Update 
1d2f0 74 68 65 20 70 61 67 65 20 66 6f 6f 74 65 72 2e  the page footer.
1d300 20 2a 2f 0a 20 20 20 20 6c 73 6d 50 75 74 55 31   */.    lsmPutU1
1d310 36 28 26 61 44 61 74 61 5b 53 45 47 4d 45 4e 54  6(&aData[SEGMENT
1d320 5f 4e 52 45 43 4f 52 44 5f 4f 46 46 53 45 54 28  _NRECORD_OFFSET(
1d330 6e 44 61 74 61 29 5d 2c 20 28 75 31 36 29 28 6e  nData)], (u16)(n
1d340 52 65 63 2b 31 29 29 3b 0a 20 20 20 20 6c 73 6d  Rec+1));.    lsm
1d350 50 75 74 55 31 36 28 26 61 44 61 74 61 5b 53 45  PutU16(&aData[SE
1d360 47 4d 45 4e 54 5f 43 45 4c 4c 50 54 52 5f 4f 46  GMENT_CELLPTR_OF
1d370 46 53 45 54 28 6e 44 61 74 61 2c 20 6e 52 65 63  FSET(nData, nRec
1d380 29 5d 2c 20 28 75 31 36 29 69 4f 66 66 29 3b 0a  )], (u16)iOff);.
1d390 20 20 20 20 69 66 28 20 66 6c 61 67 73 20 29 20      if( flags ) 
1d3a0 6c 73 6d 50 75 74 55 31 36 28 26 61 44 61 74 61  lsmPutU16(&aData
1d3b0 5b 53 45 47 4d 45 4e 54 5f 46 4c 41 47 53 5f 4f  [SEGMENT_FLAGS_O
1d3c0 46 46 53 45 54 28 6e 44 61 74 61 29 5d 2c 20 28  FFSET(nData)], (
1d3d0 75 31 36 29 66 6c 61 67 73 29 3b 0a 0a 20 20 20  u16)flags);..   
1d3e0 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 65 6e   /* Write the en
1d3f0 74 72 79 20 68 65 61 64 65 72 20 69 6e 74 6f 20  try header into 
1d400 74 68 65 20 63 75 72 72 65 6e 74 20 70 61 67 65  the current page
1d410 2e 20 2a 2f 0a 20 20 20 20 61 44 61 74 61 5b 69  . */.    aData[i
1d420 4f 66 66 2b 2b 5d 20 3d 20 28 75 38 29 65 54 79  Off++] = (u8)eTy
1d430 70 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  pe;             
1d440 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d450 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1d460 20 31 20 2a 2f 0a 20 20 20 20 69 4f 66 66 20 2b   1 */.    iOff +
1d470 3d 20 6c 73 6d 56 61 72 69 6e 74 50 75 74 33 32  = lsmVarintPut32
1d480 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c 20 69  (&aData[iOff], i
1d490 52 50 74 72 29 3b 20 20 20 20 20 20 20 20 20 20  RPtr);          
1d4a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1d4b0 2a 20 32 20 2a 2f 0a 20 20 20 20 69 4f 66 66 20  * 2 */.    iOff 
1d4c0 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 50 75 74 33  += lsmVarintPut3
1d4d0 32 28 26 61 44 61 74 61 5b 69 4f 66 66 5d 2c 20  2(&aData[iOff], 
1d4e0 6e 4b 65 79 29 3b 20 20 20 20 20 20 20 20 20 20  nKey);          
1d4f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d500 2f 2a 20 33 20 2a 2f 0a 20 20 20 20 69 66 28 20  /* 3 */.    if( 
1d510 72 74 49 73 57 72 69 74 65 28 65 54 79 70 65 29  rtIsWrite(eType)
1d520 20 29 20 69 4f 66 66 20 2b 3d 20 6c 73 6d 56 61   ) iOff += lsmVa
1d530 72 69 6e 74 50 75 74 33 32 28 26 61 44 61 74 61  rintPut32(&aData
1d540 5b 69 4f 66 66 5d 2c 20 6e 56 61 6c 29 3b 20 20  [iOff], nVal);  
1d550 20 2f 2a 20 34 20 2a 2f 0a 20 20 20 20 70 4d 65   /* 4 */.    pMe
1d560 72 67 65 2d 3e 69 4f 75 74 70 75 74 4f 66 66 20  rge->iOutputOff 
1d570 3d 20 69 4f 66 66 3b 0a 0a 20 20 20 20 2f 2a 20  = iOff;..    /* 
1d580 57 72 69 74 65 20 74 68 65 20 6b 65 79 20 61 6e  Write the key an
1d590 64 20 64 61 74 61 20 69 6e 74 6f 20 74 68 65 20  d data into the 
1d5a0 73 65 67 6d 65 6e 74 2e 20 2a 2f 0a 20 20 20 20  segment. */.    
1d5b0 61 73 73 65 72 74 28 20 69 46 50 74 72 3d 3d 70  assert( iFPtr==p
1d5c0 61 67 65 47 65 74 50 74 72 28 61 44 61 74 61 2c  ageGetPtr(aData,
1d5d0 20 6e 44 61 74 61 29 20 29 3b 0a 20 20 20 20 72   nData) );.    r
1d5e0 63 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65 72 44  c = mergeWorkerD
1d5f0 61 74 61 28 70 4d 57 2c 20 30 2c 20 69 46 50 74  ata(pMW, 0, iFPt
1d600 72 2b 69 52 50 74 72 2c 20 70 4b 65 79 2c 20 6e  r+iRPtr, pKey, n
1d610 4b 65 79 29 3b 0a 20 20 20 20 69 66 28 20 72 63  Key);.    if( rc
1d620 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 72 74 49 73  ==LSM_OK && rtIs
1d630 57 72 69 74 65 28 65 54 79 70 65 29 20 29 7b 0a  Write(eType) ){.
1d640 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53        if( rc==LS
1d650 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  M_OK ){.        
1d660 72 63 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65 72  rc = mergeWorker
1d670 44 61 74 61 28 70 4d 57 2c 20 30 2c 20 69 46 50  Data(pMW, 0, iFP
1d680 74 72 2b 69 52 50 74 72 2c 20 70 56 61 6c 2c 20  tr+iRPtr, pVal, 
1d690 6e 56 61 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 20  nVal);.      }. 
1d6a0 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
1d6b0 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  rn rc;.}.../*.**
1d6c0 20 46 72 65 65 20 61 6c 6c 20 72 65 73 6f 75 72   Free all resour
1d6d0 63 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 62 79  ces allocated by
1d6e0 20 6d 65 72 67 65 57 6f 72 6b 65 72 49 6e 69 74   mergeWorkerInit
1d6f0 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ()..*/.static vo
1d700 69 64 20 6d 65 72 67 65 57 6f 72 6b 65 72 53 68  id mergeWorkerSh
1d710 75 74 64 6f 77 6e 28 4d 65 72 67 65 57 6f 72 6b  utdown(MergeWork
1d720 65 72 20 2a 70 4d 57 2c 20 69 6e 74 20 2a 70 52  er *pMW, int *pR
1d730 63 29 7b 0a 20 20 69 6e 74 20 69 3b 20 20 20 20  c){.  int i;    
1d740 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d750 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74 6f        /* Iterato
1d760 72 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20  r variable */.  
1d770 69 6e 74 20 72 63 20 3d 20 2a 70 52 63 3b 0a 20  int rc = *pRc;. 
1d780 20 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43   MultiCursor *pC
1d790 73 72 20 3d 20 70 4d 57 2d 3e 70 43 73 72 3b 0a  sr = pMW->pCsr;.
1d7a0 0a 20 20 2f 2a 20 55 6e 6c 65 73 73 20 74 68 65  .  /* Unless the
1d7b0 20 6d 65 72 67 65 20 68 61 73 20 66 69 6e 69 73   merge has finis
1d7c0 68 65 64 2c 20 73 61 76 65 20 74 68 65 20 63 75  hed, save the cu
1d7d0 72 73 6f 72 20 70 6f 73 69 74 69 6f 6e 20 69 6e  rsor position in
1d7e0 20 74 68 65 0a 20 20 2a 2a 20 4d 65 72 67 65 2e   the.  ** Merge.
1d7f0 61 49 6e 70 75 74 5b 5d 20 61 72 72 61 79 2e 20  aInput[] array. 
1d800 53 65 65 20 66 75 6e 63 74 69 6f 6e 20 6d 65 72  See function mer
1d810 67 65 57 6f 72 6b 65 72 49 6e 69 74 28 29 20 66  geWorkerInit() f
1d820 6f 72 20 74 68 65 20 0a 20 20 2a 2a 20 63 6f 64  or the .  ** cod
1d830 65 20 74 6f 20 72 65 73 74 6f 72 65 20 61 20 63  e to restore a c
1d840 75 72 73 6f 72 20 70 6f 73 69 74 69 6f 6e 20 62  ursor position b
1d850 61 73 65 64 20 6f 6e 20 61 49 6e 70 75 74 5b 5d  ased on aInput[]
1d860 2e 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d  .  */.  if( rc==
1d870 4c 53 4d 5f 4f 4b 20 26 26 20 70 43 73 72 20 29  LSM_OK && pCsr )
1d880 7b 0a 20 20 20 20 4d 65 72 67 65 20 2a 70 4d 65  {.    Merge *pMe
1d890 72 67 65 20 3d 20 70 4d 57 2d 3e 70 4c 65 76 65  rge = pMW->pLeve
1d8a0 6c 2d 3e 70 4d 65 72 67 65 3b 0a 20 20 20 20 69  l->pMerge;.    i
1d8b0 66 28 20 6c 73 6d 4d 43 75 72 73 6f 72 56 61 6c  f( lsmMCursorVal
1d8c0 69 64 28 70 43 73 72 29 20 29 7b 0a 20 20 20 20  id(pCsr) ){.    
1d8d0 20 20 69 6e 74 20 62 42 74 72 65 65 20 3d 20 28    int bBtree = (
1d8e0 70 43 73 72 2d 3e 70 42 74 43 73 72 21 3d 30 29  pCsr->pBtCsr!=0)
1d8f0 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 50 74 72  ;.      int iPtr
1d900 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 70 4d 65 72  ;..      /* pMer
1d910 67 65 2d 3e 6e 49 6e 70 75 74 3d 3d 30 20 69 6e  ge->nInput==0 in
1d920 64 69 63 61 74 65 73 20 74 68 61 74 20 74 68 69  dicates that thi
1d930 73 20 69 73 20 61 20 46 6c 75 73 68 54 72 65 65  s is a FlushTree
1d940 28 29 20 6f 70 65 72 61 74 69 6f 6e 2e 20 2a 2f  () operation. */
1d950 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70  .      assert( p
1d960 4d 65 72 67 65 2d 3e 6e 49 6e 70 75 74 3d 3d 30  Merge->nInput==0
1d970 20 7c 7c 20 70 4d 57 2d 3e 70 4c 65 76 65 6c 2d   || pMW->pLevel-
1d980 3e 6e 52 69 67 68 74 3e 30 20 29 3b 0a 20 20 20  >nRight>0 );.   
1d990 20 20 20 61 73 73 65 72 74 28 20 70 4d 65 72 67     assert( pMerg
1d9a0 65 2d 3e 6e 49 6e 70 75 74 3d 3d 30 20 7c 7c 20  e->nInput==0 || 
1d9b0 70 4d 65 72 67 65 2d 3e 6e 49 6e 70 75 74 3d 3d  pMerge->nInput==
1d9c0 28 70 43 73 72 2d 3e 6e 50 74 72 2b 62 42 74 72  (pCsr->nPtr+bBtr
1d9d0 65 65 29 20 29 3b 0a 0a 20 20 20 20 20 20 66 6f  ee) );..      fo
1d9e0 72 28 69 3d 30 3b 20 69 3c 28 70 4d 65 72 67 65  r(i=0; i<(pMerge
1d9f0 2d 3e 6e 49 6e 70 75 74 2d 62 42 74 72 65 65 29  ->nInput-bBtree)
1da00 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
1da10 53 65 67 6d 65 6e 74 50 74 72 20 2a 70 50 74 72  SegmentPtr *pPtr
1da20 20 3d 20 26 70 43 73 72 2d 3e 61 50 74 72 5b 69   = &pCsr->aPtr[i
1da30 5d 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  ];.        if( p
1da40 50 74 72 2d 3e 70 50 67 20 29 7b 0a 20 20 20 20  Ptr->pPg ){.    
1da50 20 20 20 20 20 20 70 4d 65 72 67 65 2d 3e 61 49        pMerge->aI
1da60 6e 70 75 74 5b 69 5d 2e 69 50 67 20 3d 20 6c 73  nput[i].iPg = ls
1da70 6d 46 73 50 61 67 65 4e 75 6d 62 65 72 28 70 50  mFsPageNumber(pP
1da80 74 72 2d 3e 70 50 67 29 3b 0a 20 20 20 20 20 20  tr->pPg);.      
1da90 20 20 20 20 70 4d 65 72 67 65 2d 3e 61 49 6e 70      pMerge->aInp
1daa0 75 74 5b 69 5d 2e 69 43 65 6c 6c 20 3d 20 70 50  ut[i].iCell = pP
1dab0 74 72 2d 3e 69 43 65 6c 6c 3b 0a 20 20 20 20 20  tr->iCell;.     
1dac0 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
1dad0 20 20 20 20 70 4d 65 72 67 65 2d 3e 61 49 6e 70      pMerge->aInp
1dae0 75 74 5b 69 5d 2e 69 50 67 20 3d 20 30 3b 0a 20  ut[i].iPg = 0;. 
1daf0 20 20 20 20 20 20 20 20 20 70 4d 65 72 67 65 2d           pMerge-
1db00 3e 61 49 6e 70 75 74 5b 69 5d 2e 69 43 65 6c 6c  >aInput[i].iCell
1db10 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a   = 0;.        }.
1db20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
1db30 28 20 62 42 74 72 65 65 20 26 26 20 70 4d 65 72  ( bBtree && pMer
1db40 67 65 2d 3e 6e 49 6e 70 75 74 20 29 7b 0a 20 20  ge->nInput ){.  
1db50 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69 3d        assert( i=
1db60 3d 70 43 73 72 2d 3e 6e 50 74 72 20 29 3b 0a 20  =pCsr->nPtr );. 
1db70 20 20 20 20 20 20 20 62 74 72 65 65 43 75 72 73         btreeCurs
1db80 6f 72 50 6f 73 69 74 69 6f 6e 28 70 43 73 72 2d  orPosition(pCsr-
1db90 3e 70 42 74 43 73 72 2c 20 26 70 4d 65 72 67 65  >pBtCsr, &pMerge
1dba0 2d 3e 61 49 6e 70 75 74 5b 69 5d 29 3b 0a 20 20  ->aInput[i]);.  
1dbb0 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20      }..      /* 
1dbc0 53 74 6f 72 65 20 74 68 65 20 6c 6f 63 61 74 69  Store the locati
1dbd0 6f 6e 20 6f 66 20 74 68 65 20 73 70 6c 69 74 2d  on of the split-
1dbe0 6b 65 79 20 2a 2f 0a 20 20 20 20 20 20 69 50 74  key */.      iPt
1dbf0 72 20 3d 20 70 43 73 72 2d 3e 61 54 72 65 65 5b  r = pCsr->aTree[
1dc00 31 5d 20 2d 20 43 55 52 53 4f 52 5f 44 41 54 41  1] - CURSOR_DATA
1dc10 5f 53 45 47 4d 45 4e 54 3b 0a 20 20 20 20 20 20  _SEGMENT;.      
1dc20 69 66 28 20 69 50 74 72 3c 70 43 73 72 2d 3e 6e  if( iPtr<pCsr->n
1dc30 50 74 72 20 29 7b 0a 20 20 20 20 20 20 20 20 70  Ptr ){.        p
1dc40 4d 65 72 67 65 2d 3e 73 70 6c 69 74 6b 65 79 20  Merge->splitkey 
1dc50 3d 20 70 4d 65 72 67 65 2d 3e 61 49 6e 70 75 74  = pMerge->aInput
1dc60 5b 69 50 74 72 5d 3b 0a 20 20 20 20 20 20 7d 65  [iPtr];.      }e
1dc70 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 62 74 72  lse{.        btr
1dc80 65 65 43 75 72 73 6f 72 53 70 6c 69 74 6b 65 79  eeCursorSplitkey
1dc90 28 70 43 73 72 2d 3e 70 42 74 43 73 72 2c 20 26  (pCsr->pBtCsr, &
1dca0 70 4d 65 72 67 65 2d 3e 73 70 6c 69 74 6b 65 79  pMerge->splitkey
1dcb0 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
1dcc0 0a 0a 20 20 20 20 2f 2a 20 5a 65 72 6f 20 61 6e  ..    /* Zero an
1dcd0 79 20 66 72 65 65 20 73 70 61 63 65 20 6c 65 66  y free space lef
1dce0 74 20 6f 6e 20 74 68 65 20 66 69 6e 61 6c 20 70  t on the final p
1dcf0 61 67 65 2e 20 54 68 69 73 20 68 65 6c 70 73 20  age. This helps 
1dd00 77 69 74 68 0a 20 20 20 20 2a 2a 20 63 6f 6d 70  with.    ** comp
1dd10 72 65 73 73 69 6f 6e 20 69 66 20 75 73 69 6e 67  ression if using
1dd20 20 61 20 63 6f 6d 70 72 65 73 73 69 6f 6e 20 68   a compression h
1dd30 6f 6f 6b 2e 20 41 6e 64 20 70 72 65 76 65 6e 74  ook. And prevent
1dd40 73 20 76 61 6c 67 72 69 6e 64 0a 20 20 20 20 2a  s valgrind.    *
1dd50 2a 20 66 72 6f 6d 20 63 6f 6d 70 6c 61 69 6e 69  * from complaini
1dd60 6e 67 20 61 62 6f 75 74 20 75 6e 69 6e 69 74 69  ng about uniniti
1dd70 61 6c 69 7a 65 64 20 62 79 74 65 20 70 61 73 73  alized byte pass
1dd80 65 64 20 74 6f 20 77 72 69 74 65 28 29 2e 20 2a  ed to write(). *
1dd90 2f 0a 20 20 20 20 69 66 28 20 70 4d 57 2d 3e 70  /.    if( pMW->p
1dda0 50 61 67 65 20 29 7b 0a 20 20 20 20 20 20 69 6e  Page ){.      in
1ddb0 74 20 6e 44 61 74 61 3b 0a 20 20 20 20 20 20 75  t nData;.      u
1ddc0 38 20 2a 61 44 61 74 61 20 3d 20 66 73 50 61 67  8 *aData = fsPag
1ddd0 65 44 61 74 61 28 70 4d 57 2d 3e 70 50 61 67 65  eData(pMW->pPage
1dde0 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 20  , &nData);.     
1ddf0 20 69 6e 74 20 69 4f 66 66 20 3d 20 70 4d 65 72   int iOff = pMer
1de00 67 65 2d 3e 69 4f 75 74 70 75 74 4f 66 66 3b 0a  ge->iOutputOff;.
1de10 20 20 20 20 20 20 69 6e 74 20 69 45 6f 66 20 3d        int iEof =
1de20 20 53 45 47 4d 45 4e 54 5f 45 4f 46 28 6e 44 61   SEGMENT_EOF(nDa
1de30 74 61 2c 20 70 61 67 65 47 65 74 4e 52 65 63 28  ta, pageGetNRec(
1de40 61 44 61 74 61 2c 20 6e 44 61 74 61 29 29 3b 0a  aData, nData));.
1de50 20 20 20 20 20 20 6d 65 6d 73 65 74 28 26 61 44        memset(&aD
1de60 61 74 61 5b 69 4f 66 66 5d 2c 20 30 2c 20 69 45  ata[iOff], 0, iE
1de70 6f 66 20 2d 20 69 4f 66 66 29 3b 0a 20 20 20 20  of - iOff);.    
1de80 7d 0a 20 20 20 20 0a 20 20 20 20 70 4d 65 72 67  }.    .    pMerg
1de90 65 2d 3e 69 4f 75 74 70 75 74 4f 66 66 20 3d 20  e->iOutputOff = 
1dea0 2d 31 3b 0a 20 20 7d 0a 0a 20 20 6c 73 6d 4d 43  -1;.  }..  lsmMC
1deb0 75 72 73 6f 72 43 6c 6f 73 65 28 70 43 73 72 2c  ursorClose(pCsr,
1dec0 20 30 29 3b 0a 0a 20 20 2f 2a 20 50 65 72 73 69   0);..  /* Persi
1ded0 73 74 20 61 6e 64 20 72 65 6c 65 61 73 65 20 74  st and release t
1dee0 68 65 20 6f 75 74 70 75 74 20 70 61 67 65 2e 20  he output page. 
1def0 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d  */.  if( rc==LSM
1df00 5f 4f 4b 20 29 20 72 63 20 3d 20 6d 65 72 67 65  _OK ) rc = merge
1df10 57 6f 72 6b 65 72 50 65 72 73 69 73 74 41 6e 64  WorkerPersistAnd
1df20 52 65 6c 65 61 73 65 28 70 4d 57 29 3b 0a 20 20  Release(pMW);.  
1df30 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
1df40 20 72 63 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65   rc = mergeWorke
1df50 72 42 74 72 65 65 49 6e 64 69 72 65 63 74 28 70  rBtreeIndirect(p
1df60 4d 57 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 4c  MW);.  if( rc==L
1df70 53 4d 5f 4f 4b 20 29 20 72 63 20 3d 20 6d 65 72  SM_OK ) rc = mer
1df80 67 65 57 6f 72 6b 65 72 46 69 6e 69 73 68 48 69  geWorkerFinishHi
1df90 65 72 61 72 63 68 79 28 70 4d 57 29 3b 0a 20 20  erarchy(pMW);.  
1dfa0 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
1dfb0 20 72 63 20 3d 20 6d 65 72 67 65 57 6f 72 6b 65   rc = mergeWorke
1dfc0 72 41 64 64 50 61 64 64 69 6e 67 28 70 4d 57 29  rAddPadding(pMW)
1dfd0 3b 0a 20 20 6c 73 6d 46 73 46 6c 75 73 68 57 61  ;.  lsmFsFlushWa
1dfe0 69 74 69 6e 67 28 70 4d 57 2d 3e 70 44 62 2d 3e  iting(pMW->pDb->
1dff0 70 46 53 2c 20 26 72 63 29 3b 0a 20 20 6d 65 72  pFS, &rc);.  mer
1e000 67 65 57 6f 72 6b 65 72 52 65 6c 65 61 73 65 41  geWorkerReleaseA
1e010 6c 6c 28 70 4d 57 29 3b 0a 0a 20 20 6c 73 6d 46  ll(pMW);..  lsmF
1e020 72 65 65 28 70 4d 57 2d 3e 70 44 62 2d 3e 70 45  ree(pMW->pDb->pE
1e030 6e 76 2c 20 70 4d 57 2d 3e 61 47 6f 62 62 6c 65  nv, pMW->aGobble
1e040 29 3b 0a 20 20 70 4d 57 2d 3e 61 47 6f 62 62 6c  );.  pMW->aGobbl
1e050 65 20 3d 20 30 3b 0a 20 20 70 4d 57 2d 3e 70 43  e = 0;.  pMW->pC
1e060 73 72 20 3d 20 30 3b 0a 0a 20 20 2a 70 52 63 20  sr = 0;..  *pRc 
1e070 3d 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  = rc;.}../*.** T
1e080 68 65 20 63 75 72 73 6f 72 20 70 61 73 73 65 64  he cursor passed
1e090 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61 72   as the first ar
1e0a0 67 75 6d 65 6e 74 20 69 73 20 62 65 69 6e 67 20  gument is being 
1e0b0 75 73 65 64 20 61 73 20 74 68 65 20 69 6e 70 75  used as the inpu
1e0c0 74 20 66 6f 72 0a 2a 2a 20 61 20 6d 65 72 67 65  t for.** a merge
1e0d0 20 6f 70 65 72 61 74 69 6f 6e 2e 20 57 68 65 6e   operation. When
1e0e0 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
1e0f0 73 20 63 61 6c 6c 65 64 2c 20 2a 70 69 46 6c 61  s called, *piFla
1e100 67 73 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 0a  gs contains the.
1e110 2a 2a 20 64 61 74 61 62 61 73 65 20 65 6e 74 72  ** database entr
1e120 79 20 66 6c 61 67 73 20 66 6f 72 20 74 68 65 20  y flags for the 
1e130 63 75 72 72 65 6e 74 20 65 6e 74 72 79 2e 20 54  current entry. T
1e140 68 65 20 65 6e 74 72 79 20 61 62 6f 75 74 20 74  he entry about t
1e150 6f 20 62 65 20 77 72 69 74 74 65 6e 0a 2a 2a 20  o be written.** 
1e160 74 6f 20 74 68 65 20 6f 75 74 70 75 74 2e 0a 2a  to the output..*
1e170 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61 74 20 74  *.** Note that t
1e180 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 6f 6e 6c  his function onl
1e190 79 20 68 61 73 20 74 6f 20 77 6f 72 6b 20 66 6f  y has to work fo
1e1a0 72 20 63 75 72 73 6f 72 73 20 63 6f 6e 66 69 67  r cursors config
1e1b0 75 72 65 64 20 74 6f 20 0a 2a 2a 20 69 74 65 72  ured to .** iter
1e1c0 61 74 65 20 66 6f 72 77 61 72 64 73 20 28 6e 6f  ate forwards (no
1e1d0 74 20 62 61 63 6b 77 61 72 64 73 29 2e 0a 2a 2f  t backwards)..*/
1e1e0 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 65 72  .static void mer
1e1f0 67 65 52 61 6e 67 65 44 65 6c 65 74 65 73 28 4d  geRangeDeletes(M
1e200 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72  ultiCursor *pCsr
1e210 2c 20 69 6e 74 20 2a 70 69 56 61 6c 2c 20 69 6e  , int *piVal, in
1e220 74 20 2a 70 69 46 6c 61 67 73 29 7b 0a 20 20 69  t *piFlags){.  i
1e230 6e 74 20 66 20 3d 20 2a 70 69 46 6c 61 67 73 3b  nt f = *piFlags;
1e240 0a 20 20 69 6e 74 20 69 4b 65 79 20 3d 20 70 43  .  int iKey = pC
1e250 73 72 2d 3e 61 54 72 65 65 5b 31 5d 3b 0a 20 20  sr->aTree[1];.  
1e260 69 6e 74 20 69 3b 0a 0a 20 20 61 73 73 65 72 74  int i;..  assert
1e270 28 20 70 43 73 72 2d 3e 66 6c 61 67 73 20 26 20  ( pCsr->flags & 
1e280 43 55 52 53 4f 52 5f 4e 45 58 54 5f 4f 4b 20 29  CURSOR_NEXT_OK )
1e290 3b 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 66 6c  ;.  if( pCsr->fl
1e2a0 61 67 73 20 26 20 43 55 52 53 4f 52 5f 49 47 4e  ags & CURSOR_IGN
1e2b0 4f 52 45 5f 44 45 4c 45 54 45 20 29 7b 0a 20 20  ORE_DELETE ){.  
1e2c0 20 20 2f 2a 20 54 68 65 20 69 67 6e 6f 72 65 2d    /* The ignore-
1e2d0 64 65 6c 65 74 65 20 66 6c 61 67 20 69 73 20 73  delete flag is s
1e2e0 65 74 20 77 68 65 6e 20 74 68 65 20 6f 75 74 70  et when the outp
1e2f0 75 74 20 6f 66 20 74 68 65 20 6d 65 72 67 65 20  ut of the merge 
1e300 77 69 6c 6c 20 66 6f 72 6d 0a 20 20 20 20 2a 2a  will form.    **
1e310 20 74 68 65 20 6f 6c 64 65 73 74 20 6c 65 76 65   the oldest leve
1e320 6c 20 69 6e 20 74 68 65 20 64 61 74 61 62 61 73  l in the databas
1e330 65 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 20  e. In this case 
1e340 74 68 65 72 65 20 69 73 20 6e 6f 20 70 6f 69 6e  there is no poin
1e350 74 20 69 6e 0a 20 20 20 20 2a 2a 20 72 65 74 61  t in.    ** reta
1e360 69 6e 69 6e 67 20 61 6e 79 20 72 61 6e 67 65 2d  ining any range-
1e370 64 65 6c 65 74 65 20 66 6c 61 67 73 2e 20 20 2a  delete flags.  *
1e380 2f 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 66  /.    assert( (f
1e390 20 26 20 4c 53 4d 5f 50 4f 49 4e 54 5f 44 45 4c   & LSM_POINT_DEL
1e3a0 45 54 45 29 3d 3d 30 20 29 3b 0a 20 20 20 20 66  ETE)==0 );.    f
1e3b0 20 26 3d 20 7e 28 4c 53 4d 5f 53 54 41 52 54 5f   &= ~(LSM_START_
1e3c0 44 45 4c 45 54 45 7c 4c 53 4d 5f 45 4e 44 5f 44  DELETE|LSM_END_D
1e3d0 45 4c 45 54 45 29 3b 0a 20 20 7d 65 6c 73 65 7b  ELETE);.  }else{
1e3e0 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  .    for(i=0; i<
1e3f0 28 43 55 52 53 4f 52 5f 44 41 54 41 5f 53 45 47  (CURSOR_DATA_SEG
1e400 4d 45 4e 54 20 2b 20 70 43 73 72 2d 3e 6e 50 74  MENT + pCsr->nPt
1e410 72 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  r); i++){.      
1e420 69 66 28 20 69 21 3d 69 4b 65 79 20 29 7b 0a 20  if( i!=iKey ){. 
1e430 20 20 20 20 20 20 20 69 6e 74 20 65 54 79 70 65         int eType
1e440 3b 0a 20 20 20 20 20 20 20 20 76 6f 69 64 20 2a  ;.        void *
1e450 70 4b 65 79 3b 0a 20 20 20 20 20 20 20 20 69 6e  pKey;.        in
1e460 74 20 6e 4b 65 79 3b 0a 20 20 20 20 20 20 20 20  t nKey;.        
1e470 69 6e 74 20 72 65 73 3b 0a 20 20 20 20 20 20 20  int res;.       
1e480 20 6d 75 6c 74 69 43 75 72 73 6f 72 47 65 74 4b   multiCursorGetK
1e490 65 79 28 70 43 73 72 2c 20 69 2c 20 26 65 54 79  ey(pCsr, i, &eTy
1e4a0 70 65 2c 20 26 70 4b 65 79 2c 20 26 6e 4b 65 79  pe, &pKey, &nKey
1e4b0 29 3b 0a 0a 20 20 20 20 20 20 20 20 69 66 28 20  );..        if( 
1e4c0 70 4b 65 79 20 29 7b 0a 20 20 20 20 20 20 20 20  pKey ){.        
1e4d0 20 20 72 65 73 20 3d 20 73 6f 72 74 65 64 4b 65    res = sortedKe
1e4e0 79 43 6f 6d 70 61 72 65 28 70 43 73 72 2d 3e 70  yCompare(pCsr->p
1e4f0 44 62 2d 3e 78 43 6d 70 2c 20 0a 20 20 20 20 20  Db->xCmp, .     
1e500 20 20 20 20 20 20 20 20 20 72 74 54 6f 70 69 63           rtTopic
1e510 28 70 43 73 72 2d 3e 65 54 79 70 65 29 2c 20 70  (pCsr->eType), p
1e520 43 73 72 2d 3e 6b 65 79 2e 70 44 61 74 61 2c 20  Csr->key.pData, 
1e530 70 43 73 72 2d 3e 6b 65 79 2e 6e 44 61 74 61 2c  pCsr->key.nData,
1e540 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72  .              r
1e550 74 54 6f 70 69 63 28 65 54 79 70 65 29 2c 20 70  tTopic(eType), p
1e560 4b 65 79 2c 20 6e 4b 65 79 0a 20 20 20 20 20 20  Key, nKey.      
1e570 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 20      );.         
1e580 20 61 73 73 65 72 74 28 20 72 65 73 3c 3d 30 20   assert( res<=0 
1e590 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  );.          if(
1e5a0 20 72 65 73 3d 3d 30 20 29 7b 0a 20 20 20 20 20   res==0 ){.     
1e5b0 20 20 20 20 20 20 20 69 66 28 20 28 66 20 26 20         if( (f & 
1e5c0 28 4c 53 4d 5f 49 4e 53 45 52 54 7c 4c 53 4d 5f  (LSM_INSERT|LSM_
1e5d0 50 4f 49 4e 54 5f 44 45 4c 45 54 45 29 29 3d 3d  POINT_DELETE))==
1e5e0 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  0 ){.           
1e5f0 20 20 20 69 66 28 20 65 54 79 70 65 20 26 20 4c     if( eType & L
1e600 53 4d 5f 49 4e 53 45 52 54 20 29 7b 0a 20 20 20  SM_INSERT ){.   
1e610 20 20 20 20 20 20 20 20 20 20 20 20 20 66 20 7c               f |
1e620 3d 20 4c 53 4d 5f 49 4e 53 45 52 54 3b 0a 20 20  = LSM_INSERT;.  
1e630 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 70                *p
1e640 69 56 61 6c 20 3d 20 69 3b 0a 20 20 20 20 20 20  iVal = i;.      
1e650 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
1e660 20 20 20 20 20 20 20 20 65 6c 73 65 20 69 66 28          else if(
1e670 20 65 54 79 70 65 20 26 20 4c 53 4d 5f 50 4f 49   eType & LSM_POI
1e680 4e 54 5f 44 45 4c 45 54 45 20 29 7b 0a 20 20 20  NT_DELETE ){.   
1e690 20 20 20 20 20 20 20 20 20 20 20 20 20 66 20 7c               f |
1e6a0 3d 20 4c 53 4d 5f 50 4f 49 4e 54 5f 44 45 4c 45  = LSM_POINT_DELE
1e6b0 54 45 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  TE;.            
1e6c0 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20    }.            
1e6d0 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 20  }.            f 
1e6e0 7c 3d 20 28 65 54 79 70 65 20 26 20 28 4c 53 4d  |= (eType & (LSM
1e6f0 5f 45 4e 44 5f 44 45 4c 45 54 45 7c 4c 53 4d 5f  _END_DELETE|LSM_
1e700 53 54 41 52 54 5f 44 45 4c 45 54 45 29 29 3b 0a  START_DELETE));.
1e710 20 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20            }..   
1e720 20 20 20 20 20 20 20 69 66 28 20 69 3e 69 4b 65         if( i>iKe
1e730 79 20 26 26 20 28 65 54 79 70 65 20 26 20 4c 53  y && (eType & LS
1e740 4d 5f 45 4e 44 5f 44 45 4c 45 54 45 29 20 26 26  M_END_DELETE) &&
1e750 20 72 65 73 3c 30 20 29 7b 0a 20 20 20 20 20 20   res<0 ){.      
1e760 20 20 20 20 20 20 69 66 28 20 66 20 26 20 28 4c        if( f & (L
1e770 53 4d 5f 49 4e 53 45 52 54 7c 4c 53 4d 5f 50 4f  SM_INSERT|LSM_PO
1e780 49 4e 54 5f 44 45 4c 45 54 45 29 20 29 7b 0a 20  INT_DELETE) ){. 
1e790 20 20 20 20 20 20 20 20 20 20 20 20 20 66 20 7c               f |
1e7a0 3d 20 28 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45 54  = (LSM_END_DELET
1e7b0 45 7c 4c 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45  E|LSM_START_DELE
1e7c0 54 45 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  TE);.           
1e7d0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
1e7e0 20 20 20 20 20 20 66 20 3d 20 30 3b 0a 20 20 20        f = 0;.   
1e7f0 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
1e800 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
1e810 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
1e820 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
1e830 7d 0a 0a 20 20 20 20 61 73 73 65 72 74 28 20 28  }..    assert( (
1e840 66 20 26 20 4c 53 4d 5f 49 4e 53 45 52 54 29 3d  f & LSM_INSERT)=
1e850 3d 30 20 7c 7c 20 28 66 20 26 20 4c 53 4d 5f 50  =0 || (f & LSM_P
1e860 4f 49 4e 54 5f 44 45 4c 45 54 45 29 3d 3d 30 20  OINT_DELETE)==0 
1e870 29 3b 0a 20 20 20 20 69 66 28 20 28 66 20 26 20  );.    if( (f & 
1e880 4c 53 4d 5f 53 54 41 52 54 5f 44 45 4c 45 54 45  LSM_START_DELETE
1e890 29 20 0a 20 20 20 20 20 26 26 20 28 66 20 26 20  ) .     && (f & 
1e8a0 4c 53 4d 5f 45 4e 44 5f 44 45 4c 45 54 45 29 20  LSM_END_DELETE) 
1e8b0 0a 20 20 20 20 20 26 26 20 28 66 20 26 20 4c 53  .     && (f & LS
1e8c0 4d 5f 50 4f 49 4e 54 5f 44 45 4c 45 54 45 20 29  M_POINT_DELETE )
1e8d0 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 66 20  .    ){.      f 
1e8e0 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  = 0;.    }.  }..
1e8f0 20 20 2a 70 69 46 6c 61 67 73 20 3d 20 66 3b 0a    *piFlags = f;.
1e900 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65  }..static int me
1e910 72 67 65 57 6f 72 6b 65 72 53 74 65 70 28 4d 65  rgeWorkerStep(Me
1e920 72 67 65 57 6f 72 6b 65 72 20 2a 70 4d 57 29 7b  rgeWorker *pMW){
1e930 0a 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62 20 3d  .  lsm_db *pDb =
1e940 20 70 4d 57 2d 3e 70 44 62 3b 20 20 20 20 20 20   pMW->pDb;      
1e950 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e   /* Database han
1e960 64 6c 65 20 2a 2f 0a 20 20 4d 75 6c 74 69 43 75  dle */.  MultiCu
1e970 72 73 6f 72 20 2a 70 43 73 72 3b 20 20 20 20 20  rsor *pCsr;     
1e980 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73 6f 72         /* Cursor
1e990 20 74 6f 20 72 65 61 64 20 69 6e 70 75 74 20 64   to read input d
1e9a0 61 74 61 20 66 72 6f 6d 20 2a 2f 0a 20 20 69 6e  ata from */.  in
1e9b0 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20  t rc = LSM_OK;  
1e9c0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
1e9d0 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
1e9e0 69 6e 74 20 65 54 79 70 65 3b 20 20 20 20 20 20  int eType;      
1e9f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1ea00 20 53 4f 52 54 45 44 5f 53 45 50 41 52 41 54 4f   SORTED_SEPARATO
1ea10 52 2c 20 57 52 49 54 45 20 6f 72 20 44 45 4c 45  R, WRITE or DELE
1ea20 54 45 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 4b  TE */.  void *pK
1ea30 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 20 20 20  ey; int nKey;   
1ea40 20 20 20 20 20 20 2f 2a 20 4b 65 79 20 2a 2f 0a        /* Key */.
1ea50 20 20 4c 73 6d 50 67 6e 6f 20 69 50 74 72 3b 0a    LsmPgno iPtr;.
1ea60 20 20 69 6e 74 20 69 56 61 6c 3b 0a 0a 20 20 70    int iVal;..  p
1ea70 43 73 72 20 3d 20 70 4d 57 2d 3e 70 43 73 72 3b  Csr = pMW->pCsr;
1ea80 0a 0a 20 20 2f 2a 20 50 75 6c 6c 20 74 68 65 20  ..  /* Pull the 
1ea90 6e 65 78 74 20 72 65 63 6f 72 64 20 6f 75 74 20  next record out 
1eaa0 6f 66 20 74 68 65 20 73 6f 75 72 63 65 20 63 75  of the source cu
1eab0 72 73 6f 72 2e 20 2a 2f 0a 20 20 6c 73 6d 4d 43  rsor. */.  lsmMC
1eac0 75 72 73 6f 72 4b 65 79 28 70 43 73 72 2c 20 26  ursorKey(pCsr, &
1ead0 70 4b 65 79 2c 20 26 6e 4b 65 79 29 3b 0a 20 20  pKey, &nKey);.  
1eae0 65 54 79 70 65 20 3d 20 70 43 73 72 2d 3e 65 54  eType = pCsr->eT
1eaf0 79 70 65 3b 0a 0a 20 20 2f 2a 20 46 69 67 75 72  ype;..  /* Figur
1eb00 65 20 6f 75 74 20 69 66 20 74 68 65 20 6f 75 74  e out if the out
1eb10 70 75 74 20 72 65 63 6f 72 64 20 6d 61 79 20 68  put record may h
1eb20 61 76 65 20 61 20 64 69 66 66 65 72 65 6e 74 20  ave a different 
1eb30 70 6f 69 6e 74 65 72 20 76 61 6c 75 65 0a 20 20  pointer value.  
1eb40 2a 2a 20 74 68 61 6e 20 74 68 65 20 70 72 65 76  ** than the prev
1eb50 69 6f 75 73 2e 20 54 68 69 73 20 69 73 20 74 68  ious. This is th
1eb60 65 20 63 61 73 65 20 69 66 20 74 68 65 20 63 75  e case if the cu
1eb70 72 72 65 6e 74 20 6b 65 79 20 69 73 20 69 64 65  rrent key is ide
1eb80 6e 74 69 63 61 6c 20 74 6f 0a 20 20 2a 2a 20 61  ntical to.  ** a
1eb90 20 6b 65 79 20 74 68 61 74 20 61 70 70 65 61 72   key that appear
1eba0 73 20 69 6e 20 74 68 65 20 6c 6f 77 65 73 74 20  s in the lowest 
1ebb0 6c 65 76 65 6c 20 72 75 6e 20 62 65 69 6e 67 20  level run being 
1ebc0 6d 65 72 67 65 64 2e 20 49 66 20 73 6f 2c 20 73  merged. If so, s
1ebd0 65 74 20 0a 20 20 2a 2a 20 69 50 74 72 20 74 6f  et .  ** iPtr to
1ebe0 20 74 68 65 20 61 62 73 6f 6c 75 74 65 20 70 6f   the absolute po
1ebf0 69 6e 74 65 72 20 76 61 6c 75 65 2e 20 49 66 20  inter value. If 
1ec00 6e 6f 74 2c 20 6c 65 61 76 65 20 69 50 74 72 20  not, leave iPtr 
1ec10 73 65 74 20 74 6f 20 7a 65 72 6f 2c 20 0a 20 20  set to zero, .  
1ec20 2a 2a 20 69 6e 64 69 63 61 74 69 6e 67 20 74 68  ** indicating th
1ec30 61 74 20 74 68 65 20 6f 75 74 70 75 74 20 70 6f  at the output po
1ec40 69 6e 74 65 72 20 76 61 6c 75 65 20 73 68 6f 75  inter value shou
1ec50 6c 64 20 62 65 20 61 20 63 6f 70 79 20 6f 66 20  ld be a copy of 
1ec60 74 68 65 20 70 6f 69 6e 74 65 72 20 0a 20 20 2a  the pointer .  *
1ec70 2a 20 76 61 6c 75 65 20 77 72 69 74 74 65 6e 20  * value written 
1ec80 77 69 74 68 20 74 68 65 20 70 72 65 76 69 6f 75  with the previou
1ec90 73 20 6b 65 79 2e 20 20 2a 2f 0a 20 20 69 50 74  s key.  */.  iPt
1eca0 72 20 3d 20 28 70 43 73 72 2d 3e 70 50 72 65 76  r = (pCsr->pPrev
1ecb0 4d 65 72 67 65 50 74 72 20 3f 20 2a 70 43 73 72  MergePtr ? *pCsr
1ecc0 2d 3e 70 50 72 65 76 4d 65 72 67 65 50 74 72 20  ->pPrevMergePtr 
1ecd0 3a 20 30 29 3b 0a 20 20 69 66 28 20 70 43 73 72  : 0);.  if( pCsr
1ece0 2d 3e 70 42 74 43 73 72 20 29 7b 0a 20 20 20 20  ->pBtCsr ){.    
1ecf0 42 74 72 65 65 43 75 72 73 6f 72 20 2a 70 42 74  BtreeCursor *pBt
1ed00 43 73 72 20 3d 20 70 43 73 72 2d 3e 70 42 74 43  Csr = pCsr->pBtC
1ed10 73 72 3b 0a 20 20 20 20 69 66 28 20 70 42 74 43  sr;.    if( pBtC
1ed20 73 72 2d 3e 70 4b 65 79 20 29 7b 0a 20 20 20 20  sr->pKey ){.    
1ed30 20 20 69 6e 74 20 72 65 73 20 3d 20 72 74 54 6f    int res = rtTo
1ed40 70 69 63 28 70 42 74 43 73 72 2d 3e 65 54 79 70  pic(pBtCsr->eTyp
1ed50 65 29 20 2d 20 72 74 54 6f 70 69 63 28 65 54 79  e) - rtTopic(eTy
1ed60 70 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  pe);.      if( r
1ed70 65 73 3d 3d 30 20 29 20 72 65 73 20 3d 20 70 44  es==0 ) res = pD
1ed80 62 2d 3e 78 43 6d 70 28 70 42 74 43 73 72 2d 3e  b->xCmp(pBtCsr->
1ed90 70 4b 65 79 2c 20 70 42 74 43 73 72 2d 3e 6e 4b  pKey, pBtCsr->nK
1eda0 65 79 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b  ey, pKey, nKey);
1edb0 0a 20 20 20 20 20 20 69 66 28 20 30 3d 3d 72 65  .      if( 0==re
1edc0 73 20 29 20 69 50 74 72 20 3d 20 70 42 74 43 73  s ) iPtr = pBtCs
1edd0 72 2d 3e 69 50 74 72 3b 0a 20 20 20 20 20 20 61  r->iPtr;.      a
1ede0 73 73 65 72 74 28 20 72 65 73 3e 3d 30 20 29 3b  ssert( res>=0 );
1edf0 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69  .    }.  }else i
1ee00 66 28 20 70 43 73 72 2d 3e 6e 50 74 72 20 29 7b  f( pCsr->nPtr ){
1ee10 0a 20 20 20 20 53 65 67 6d 65 6e 74 50 74 72 20  .    SegmentPtr 
1ee20 2a 70 50 74 72 20 3d 20 26 70 43 73 72 2d 3e 61  *pPtr = &pCsr->a
1ee30 50 74 72 5b 70 43 73 72 2d 3e 6e 50 74 72 2d 31  Ptr[pCsr->nPtr-1
1ee40 5d 3b 0a 20 20 20 20 69 66 28 20 70 50 74 72 2d  ];.    if( pPtr-
1ee50 3e 70 50 67 0a 20 20 20 20 20 26 26 20 30 3d 3d  >pPg.     && 0==
1ee60 70 44 62 2d 3e 78 43 6d 70 28 70 50 74 72 2d 3e  pDb->xCmp(pPtr->
1ee70 70 4b 65 79 2c 20 70 50 74 72 2d 3e 6e 4b 65 79  pKey, pPtr->nKey
1ee80 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 0a 20 20  , pKey, nKey).  
1ee90 20 20 29 7b 0a 20 20 20 20 20 20 69 50 74 72 20    ){.      iPtr 
1eea0 3d 20 70 50 74 72 2d 3e 69 50 74 72 2b 70 50 74  = pPtr->iPtr+pPt
1eeb0 72 2d 3e 69 50 67 50 74 72 3b 0a 20 20 20 20 7d  r->iPgPtr;.    }
1eec0 0a 20 20 7d 0a 0a 20 20 69 56 61 6c 20 3d 20 70  .  }..  iVal = p
1eed0 43 73 72 2d 3e 61 54 72 65 65 5b 31 5d 3b 0a 20  Csr->aTree[1];. 
1eee0 20 6d 65 72 67 65 52 61 6e 67 65 44 65 6c 65 74   mergeRangeDelet
1eef0 65 73 28 70 43 73 72 2c 20 26 69 56 61 6c 2c 20  es(pCsr, &iVal, 
1ef00 26 65 54 79 70 65 29 3b 0a 0a 20 20 69 66 28 20  &eType);..  if( 
1ef10 65 54 79 70 65 21 3d 30 20 29 7b 0a 20 20 20 20  eType!=0 ){.    
1ef20 69 66 28 20 70 4d 57 2d 3e 61 47 6f 62 62 6c 65  if( pMW->aGobble
1ef30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 47   ){.      int iG
1ef40 6f 62 62 6c 65 20 3d 20 70 43 73 72 2d 3e 61 54  obble = pCsr->aT
1ef50 72 65 65 5b 31 5d 20 2d 20 43 55 52 53 4f 52 5f  ree[1] - CURSOR_
1ef60 44 41 54 41 5f 53 45 47 4d 45 4e 54 3b 0a 20 20  DATA_SEGMENT;.  
1ef70 20 20 20 20 69 66 28 20 69 47 6f 62 62 6c 65 3c      if( iGobble<
1ef80 70 43 73 72 2d 3e 6e 50 74 72 20 26 26 20 69 47  pCsr->nPtr && iG
1ef90 6f 62 62 6c 65 3e 3d 30 20 29 7b 0a 20 20 20 20  obble>=0 ){.    
1efa0 20 20 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a      SegmentPtr *
1efb0 70 47 6f 62 62 6c 65 20 3d 20 26 70 43 73 72 2d  pGobble = &pCsr-
1efc0 3e 61 50 74 72 5b 69 47 6f 62 62 6c 65 5d 3b 0a  >aPtr[iGobble];.
1efd0 20 20 20 20 20 20 20 20 69 66 28 20 28 70 47 6f          if( (pGo
1efe0 62 62 6c 65 2d 3e 66 6c 61 67 73 20 26 20 50 47  bble->flags & PG
1eff0 46 54 52 5f 53 4b 49 50 5f 54 48 49 53 5f 46 4c  FTR_SKIP_THIS_FL
1f000 41 47 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  AG)==0 ){.      
1f010 20 20 20 20 70 4d 57 2d 3e 61 47 6f 62 62 6c 65      pMW->aGobble
1f020 5b 69 47 6f 62 62 6c 65 5d 20 3d 20 6c 73 6d 46  [iGobble] = lsmF
1f030 73 50 61 67 65 4e 75 6d 62 65 72 28 70 47 6f 62  sPageNumber(pGob
1f040 62 6c 65 2d 3e 70 50 67 29 3b 0a 20 20 20 20 20  ble->pPg);.     
1f050 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
1f060 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68   }..    /* If th
1f070 69 73 20 69 73 20 61 20 73 65 70 61 72 61 74 6f  is is a separato
1f080 72 20 6b 65 79 20 61 6e 64 20 77 65 20 6b 6e 6f  r key and we kno
1f090 77 20 74 68 61 74 20 74 68 65 20 6f 75 74 70 75  w that the outpu
1f0a0 74 20 70 6f 69 6e 74 65 72 20 68 61 73 20 6e 6f  t pointer has no
1f0b0 74 0a 20 20 20 20 2a 2a 20 63 68 61 6e 67 65 64  t.    ** changed
1f0c0 2c 20 74 68 65 72 65 20 69 73 20 6e 6f 20 70 6f  , there is no po
1f0d0 69 6e 74 20 69 6e 20 77 72 69 74 69 6e 67 20 61  int in writing a
1f0e0 6e 20 6f 75 74 70 75 74 20 72 65 63 6f 72 64 2e  n output record.
1f0f0 20 4f 74 68 65 72 77 69 73 65 2c 0a 20 20 20 20   Otherwise,.    
1f100 2a 2a 20 70 72 6f 63 65 65 64 2e 20 2a 2f 0a 20  ** proceed. */. 
1f110 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
1f120 4b 20 26 26 20 28 72 74 49 73 53 65 70 61 72 61  K && (rtIsSepara
1f130 74 6f 72 28 65 54 79 70 65 29 3d 3d 30 20 7c 7c  tor(eType)==0 ||
1f140 20 69 50 74 72 21 3d 30 29 20 29 7b 0a 20 20 20   iPtr!=0) ){.   
1f150 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20     /* Write the 
1f160 72 65 63 6f 72 64 20 69 6e 74 6f 20 74 68 65 20  record into the 
1f170 6d 61 69 6e 20 72 75 6e 2e 20 2a 2f 0a 20 20 20  main run. */.   
1f180 20 20 20 76 6f 69 64 20 2a 70 56 61 6c 3b 20 69     void *pVal; i
1f190 6e 74 20 6e 56 61 6c 3b 0a 20 20 20 20 20 20 72  nt nVal;.      r
1f1a0 63 20 3d 20 6d 75 6c 74 69 43 75 72 73 6f 72 47  c = multiCursorG
1f1b0 65 74 56 61 6c 28 70 43 73 72 2c 20 69 56 61 6c  etVal(pCsr, iVal
1f1c0 2c 20 26 70 56 61 6c 2c 20 26 6e 56 61 6c 29 3b  , &pVal, &nVal);
1f1d0 0a 20 20 20 20 20 20 69 66 28 20 70 56 61 6c 20  .      if( pVal 
1f1e0 26 26 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b  && rc==LSM_OK ){
1f1f0 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28  .        assert(
1f200 20 6e 56 61 6c 3e 3d 30 20 29 3b 0a 20 20 20 20   nVal>=0 );.    
1f210 20 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64 42      rc = sortedB
1f220 6c 6f 62 53 65 74 28 70 44 62 2d 3e 70 45 6e 76  lobSet(pDb->pEnv
1f230 2c 20 26 70 43 73 72 2d 3e 76 61 6c 2c 20 70 56  , &pCsr->val, pV
1f240 61 6c 2c 20 6e 56 61 6c 29 3b 0a 20 20 20 20 20  al, nVal);.     
1f250 20 20 20 70 56 61 6c 20 3d 20 70 43 73 72 2d 3e     pVal = pCsr->
1f260 76 61 6c 2e 70 44 61 74 61 3b 0a 20 20 20 20 20  val.pData;.     
1f270 20 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d   }.      if( rc=
1f280 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  =LSM_OK ){.     
1f290 20 20 20 72 63 20 3d 20 6d 65 72 67 65 57 6f 72     rc = mergeWor
1f2a0 6b 65 72 57 72 69 74 65 28 70 4d 57 2c 20 65 54  kerWrite(pMW, eT
1f2b0 79 70 65 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 2c  ype, pKey, nKey,
1f2c0 20 70 56 61 6c 2c 20 6e 56 61 6c 2c 20 28 69 6e   pVal, nVal, (in
1f2d0 74 29 69 50 74 72 29 3b 0a 20 20 20 20 20 20 7d  t)iPtr);.      }
1f2e0 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
1f2f0 20 41 64 76 61 6e 63 65 20 74 68 65 20 63 75 72   Advance the cur
1f300 73 6f 72 20 74 6f 20 74 68 65 20 6e 65 78 74 20  sor to the next 
1f310 69 6e 70 75 74 20 72 65 63 6f 72 64 20 28 61 73  input record (as
1f320 73 75 6d 69 6e 67 20 6f 6e 65 20 65 78 69 73 74  suming one exist
1f330 73 29 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  s). */.  assert(
1f340 20 6c 73 6d 4d 43 75 72 73 6f 72 56 61 6c 69 64   lsmMCursorValid
1f350 28 70 4d 57 2d 3e 70 43 73 72 29 20 29 3b 0a 20  (pMW->pCsr) );. 
1f360 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
1f370 29 20 72 63 20 3d 20 6c 73 6d 4d 43 75 72 73 6f  ) rc = lsmMCurso
1f380 72 4e 65 78 74 28 70 4d 57 2d 3e 70 43 73 72 29  rNext(pMW->pCsr)
1f390 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  ;..  return rc;.
1f3a0 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65  }..static int me
1f3b0 72 67 65 57 6f 72 6b 65 72 44 6f 6e 65 28 4d 65  rgeWorkerDone(Me
1f3c0 72 67 65 57 6f 72 6b 65 72 20 2a 70 4d 57 29 7b  rgeWorker *pMW){
1f3d0 0a 20 20 72 65 74 75 72 6e 20 70 4d 57 2d 3e 70  .  return pMW->p
1f3e0 43 73 72 3d 3d 30 20 7c 7c 20 21 6c 73 6d 4d 43  Csr==0 || !lsmMC
1f3f0 75 72 73 6f 72 56 61 6c 69 64 28 70 4d 57 2d 3e  ursorValid(pMW->
1f400 70 43 73 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  pCsr);.}..static
1f410 20 76 6f 69 64 20 73 6f 72 74 65 64 46 72 65 65   void sortedFree
1f420 4c 65 76 65 6c 28 6c 73 6d 5f 65 6e 76 20 2a 70  Level(lsm_env *p
1f430 45 6e 76 2c 20 4c 65 76 65 6c 20 2a 70 29 7b 0a  Env, Level *p){.
1f440 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 6c    if( p ){.    l
1f450 73 6d 46 72 65 65 28 70 45 6e 76 2c 20 70 2d 3e  smFree(pEnv, p->
1f460 70 53 70 6c 69 74 4b 65 79 29 3b 0a 20 20 20 20  pSplitKey);.    
1f470 6c 73 6d 46 72 65 65 28 70 45 6e 76 2c 20 70 2d  lsmFree(pEnv, p-
1f480 3e 70 4d 65 72 67 65 29 3b 0a 20 20 20 20 6c 73  >pMerge);.    ls
1f490 6d 46 72 65 65 28 70 45 6e 76 2c 20 70 2d 3e 61  mFree(pEnv, p->a
1f4a0 52 68 73 29 3b 0a 20 20 20 20 6c 73 6d 46 72 65  Rhs);.    lsmFre
1f4b0 65 28 70 45 6e 76 2c 20 70 29 3b 0a 20 20 7d 0a  e(pEnv, p);.  }.
1f4c0 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73  }..static void s
1f4d0 6f 72 74 65 64 49 6e 76 6f 6b 65 57 6f 72 6b 48  ortedInvokeWorkH
1f4e0 6f 6f 6b 28 6c 73 6d 5f 64 62 20 2a 70 44 62 29  ook(lsm_db *pDb)
1f4f0 7b 0a 20 20 69 66 28 20 70 44 62 2d 3e 78 57 6f  {.  if( pDb->xWo
1f500 72 6b 20 29 7b 0a 20 20 20 20 70 44 62 2d 3e 78  rk ){.    pDb->x
1f510 57 6f 72 6b 28 70 44 62 2c 20 70 44 62 2d 3e 70  Work(pDb, pDb->p
1f520 57 6f 72 6b 43 74 78 29 3b 0a 20 20 7d 0a 7d 0a  WorkCtx);.  }.}.
1f530 0a 73 74 61 74 69 63 20 69 6e 74 20 73 6f 72 74  .static int sort
1f540 65 64 4e 65 77 54 6f 70 6c 65 76 65 6c 28 0a 20  edNewToplevel(. 
1f550 20 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20   lsm_db *pDb,   
1f560 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f570 20 2f 2a 20 43 6f 6e 6e 65 63 74 69 6f 6e 20 68   /* Connection h
1f580 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 65  andle */.  int e
1f590 54 72 65 65 2c 20 20 20 20 20 20 20 20 20 20 20  Tree,           
1f5a0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e             /* On
1f5b0 65 20 6f 66 20 74 68 65 20 54 52 45 45 5f 58 58  e of the TREE_XX
1f5c0 58 20 63 6f 6e 73 74 61 6e 74 73 20 2a 2f 0a 20  X constants */. 
1f5d0 20 69 6e 74 20 2a 70 6e 57 72 69 74 65 20 20 20   int *pnWrite   
1f5e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f5f0 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72 20   /* OUT: Number 
1f600 6f 66 20 64 61 74 61 62 61 73 65 20 70 61 67 65  of database page
1f610 73 20 77 72 69 74 74 65 6e 20 2a 2f 0a 29 7b 0a  s written */.){.
1f620 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f    int rc = LSM_O
1f630 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  K;              
1f640 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65    /* Return Code
1f650 20 2a 2f 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f   */.  MultiCurso
1f660 72 20 2a 70 43 73 72 20 3d 20 30 3b 0a 20 20 4c  r *pCsr = 0;.  L
1f670 65 76 65 6c 20 2a 70 4e 65 78 74 20 3d 20 30 3b  evel *pNext = 0;
1f680 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1f690 2a 20 54 68 65 20 63 75 72 72 65 6e 74 20 74 6f  * The current to
1f6a0 70 20 6c 65 76 65 6c 20 2a 2f 0a 20 20 4c 65 76  p level */.  Lev
1f6b0 65 6c 20 2a 70 4e 65 77 3b 20 20 20 20 20 20 20  el *pNew;       
1f6c0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1f6d0 54 68 65 20 6e 65 77 20 6c 65 76 65 6c 20 69 74  The new level it
1f6e0 73 65 6c 66 20 2a 2f 0a 20 20 53 65 67 6d 65 6e  self */.  Segmen
1f6f0 74 20 2a 70 4c 69 6e 6b 65 64 20 3d 20 30 3b 20  t *pLinked = 0; 
1f700 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 65 6c            /* Del
1f710 65 74 65 20 73 65 70 61 72 61 74 6f 72 73 20 66  ete separators f
1f720 72 6f 6d 20 74 68 69 73 20 73 65 67 6d 65 6e 74  rom this segment
1f730 20 2a 2f 0a 20 20 4c 65 76 65 6c 20 2a 70 44 65   */.  Level *pDe
1f740 6c 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  l = 0;          
1f750 20 20 20 20 20 20 2f 2a 20 44 65 6c 65 74 65 20        /* Delete 
1f760 74 68 69 73 20 65 6e 74 69 72 65 20 6c 65 76 65  this entire leve
1f770 6c 20 2a 2f 0a 20 20 69 6e 74 20 6e 57 72 69 74  l */.  int nWrit
1f780 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  e = 0;          
1f790 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
1f7a0 20 6f 66 20 64 61 74 61 62 61 73 65 20 70 61 67   of database pag
1f7b0 65 73 20 77 72 69 74 74 65 6e 20 2a 2f 0a 20 20  es written */.  
1f7c0 46 72 65 65 6c 69 73 74 20 66 72 65 65 6c 69 73  Freelist freelis
1f7d0 74 3b 0a 0a 20 20 69 66 28 20 65 54 72 65 65 21  t;..  if( eTree!
1f7e0 3d 54 52 45 45 5f 4e 4f 4e 45 20 29 7b 0a 20 20  =TREE_NONE ){.  
1f7f0 20 20 72 63 20 3d 20 6c 73 6d 53 68 6d 43 61 63    rc = lsmShmCac
1f800 68 65 43 68 75 6e 6b 73 28 70 44 62 2c 20 70 44  heChunks(pDb, pD
1f810 62 2d 3e 74 72 65 65 68 64 72 2e 6e 43 68 75 6e  b->treehdr.nChun
1f820 6b 29 3b 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72  k);.  }..  asser
1f830 74 28 20 70 44 62 2d 3e 62 55 73 65 46 72 65 65  t( pDb->bUseFree
1f840 6c 69 73 74 3d 3d 30 20 29 3b 0a 20 20 70 44 62  list==0 );.  pDb
1f850 2d 3e 70 46 72 65 65 6c 69 73 74 20 3d 20 26 66  ->pFreelist = &f
1f860 72 65 65 6c 69 73 74 3b 0a 20 20 70 44 62 2d 3e  reelist;.  pDb->
1f870 62 55 73 65 46 72 65 65 6c 69 73 74 20 3d 20 31  bUseFreelist = 1
1f880 3b 0a 20 20 6d 65 6d 73 65 74 28 26 66 72 65 65  ;.  memset(&free
1f890 6c 69 73 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28  list, 0, sizeof(
1f8a0 66 72 65 65 6c 69 73 74 29 29 3b 0a 0a 20 20 2f  freelist));..  /
1f8b0 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68 65 20 6e  * Allocate the n
1f8c0 65 77 20 6c 65 76 65 6c 20 73 74 72 75 63 74 75  ew level structu
1f8d0 72 65 20 74 6f 20 77 72 69 74 65 20 74 6f 2e 20  re to write to. 
1f8e0 2a 2f 0a 20 20 70 4e 65 78 74 20 3d 20 6c 73 6d  */.  pNext = lsm
1f8f0 44 62 53 6e 61 70 73 68 6f 74 4c 65 76 65 6c 28  DbSnapshotLevel(
1f900 70 44 62 2d 3e 70 57 6f 72 6b 65 72 29 3b 0a 20  pDb->pWorker);. 
1f910 20 70 4e 65 77 20 3d 20 28 4c 65 76 65 6c 20 2a   pNew = (Level *
1f920 29 6c 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63  )lsmMallocZeroRc
1f930 28 70 44 62 2d 3e 70 45 6e 76 2c 20 73 69 7a 65  (pDb->pEnv, size
1f940 6f 66 28 4c 65 76 65 6c 29 2c 20 26 72 63 29 3b  of(Level), &rc);
1f950 0a 20 20 69 66 28 20 70 4e 65 77 20 29 7b 0a 20  .  if( pNew ){. 
1f960 20 20 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20 3d     pNew->pNext =
1f970 20 70 4e 65 78 74 3b 0a 20 20 20 20 6c 73 6d 44   pNext;.    lsmD
1f980 62 53 6e 61 70 73 68 6f 74 53 65 74 4c 65 76 65  bSnapshotSetLeve
1f990 6c 28 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2c 20  l(pDb->pWorker, 
1f9a0 70 4e 65 77 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  pNew);.  }..  /*
1f9b0 20 43 72 65 61 74 65 20 61 20 63 75 72 73 6f 72   Create a cursor
1f9c0 20 74 6f 20 67 61 74 68 65 72 20 74 68 65 20 64   to gather the d
1f9d0 61 74 61 20 72 65 71 75 69 72 65 64 20 62 79 20  ata required by 
1f9e0 74 68 65 20 6e 65 77 20 73 65 67 6d 65 6e 74 2e  the new segment.
1f9f0 20 54 68 65 20 6e 65 77 0a 20 20 2a 2a 20 73 65   The new.  ** se
1fa00 67 6d 65 6e 74 20 63 6f 6e 74 61 69 6e 73 20 65  gment contains e
1fa10 76 65 72 79 74 68 69 6e 67 20 69 6e 20 74 68 65  verything in the
1fa20 20 74 72 65 65 20 61 6e 64 20 70 6f 69 6e 74 65   tree and pointe
1fa30 72 73 20 74 6f 20 74 68 65 20 6e 65 78 74 20 73  rs to the next s
1fa40 65 67 6d 65 6e 74 0a 20 20 2a 2a 20 69 6e 20 74  egment.  ** in t
1fa50 68 65 20 64 61 74 61 62 61 73 65 20 28 69 66 20  he database (if 
1fa60 61 6e 79 29 2e 20 20 2a 2f 0a 20 20 70 43 73 72  any).  */.  pCsr
1fa70 20 3d 20 6d 75 6c 74 69 43 75 72 73 6f 72 4e 65   = multiCursorNe
1fa80 77 28 70 44 62 2c 20 26 72 63 29 3b 0a 20 20 69  w(pDb, &rc);.  i
1fa90 66 28 20 70 43 73 72 20 29 7b 0a 20 20 20 20 70  f( pCsr ){.    p
1faa0 43 73 72 2d 3e 70 44 62 20 3d 20 70 44 62 3b 0a  Csr->pDb = pDb;.
1fab0 20 20 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75      rc = multiCu
1fac0 72 73 6f 72 56 69 73 69 74 46 72 65 65 6c 69 73  rsorVisitFreelis
1fad0 74 28 70 43 73 72 29 3b 0a 20 20 20 20 69 66 28  t(pCsr);.    if(
1fae0 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20   rc==LSM_OK ){. 
1faf0 20 20 20 20 20 72 63 20 3d 20 6d 75 6c 74 69 43       rc = multiC
1fb00 75 72 73 6f 72 41 64 64 54 72 65 65 28 70 43 73  ursorAddTree(pCs
1fb10 72 2c 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2c  r, pDb->pWorker,
1fb20 20 65 54 72 65 65 29 3b 0a 20 20 20 20 7d 0a 20   eTree);.    }. 
1fb30 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
1fb40 4b 20 26 26 20 70 4e 65 78 74 20 26 26 20 70 4e  K && pNext && pN
1fb50 65 78 74 2d 3e 70 4d 65 72 67 65 3d 3d 30 20 29  ext->pMerge==0 )
1fb60 7b 0a 20 20 20 20 20 20 69 66 28 20 28 70 4e 65  {.      if( (pNe
1fb70 78 74 2d 3e 66 6c 61 67 73 20 26 20 4c 45 56 45  xt->flags & LEVE
1fb80 4c 5f 46 52 45 45 4c 49 53 54 5f 4f 4e 4c 59 29  L_FREELIST_ONLY)
1fb90 20 29 7b 0a 20 20 20 20 20 20 20 20 70 44 65 6c   ){.        pDel
1fba0 20 3d 20 70 4e 65 78 74 3b 0a 20 20 20 20 20 20   = pNext;.      
1fbb0 20 20 70 43 73 72 2d 3e 61 50 74 72 20 3d 20 6c    pCsr->aPtr = l
1fbc0 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28 70  smMallocZeroRc(p
1fbd0 44 62 2d 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66  Db->pEnv, sizeof
1fbe0 28 53 65 67 6d 65 6e 74 50 74 72 29 2c 20 26 72  (SegmentPtr), &r
1fbf0 63 29 3b 0a 20 20 20 20 20 20 20 20 6d 75 6c 74  c);.        mult
1fc00 69 43 75 72 73 6f 72 41 64 64 4f 6e 65 28 70 43  iCursorAddOne(pC
1fc10 73 72 2c 20 70 4e 65 78 74 2c 20 26 72 63 29 3b  sr, pNext, &rc);
1fc20 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28  .      }else if(
1fc30 20 65 54 72 65 65 21 3d 54 52 45 45 5f 4e 4f 4e   eTree!=TREE_NON
1fc40 45 20 26 26 20 70 4e 65 78 74 2d 3e 6c 68 73 2e  E && pNext->lhs.
1fc50 69 52 6f 6f 74 20 29 7b 0a 20 20 20 20 20 20 20  iRoot ){.       
1fc60 20 70 4c 69 6e 6b 65 64 20 3d 20 26 70 4e 65 78   pLinked = &pNex
1fc70 74 2d 3e 6c 68 73 3b 0a 20 20 20 20 20 20 20 20  t->lhs;.        
1fc80 72 63 20 3d 20 62 74 72 65 65 43 75 72 73 6f 72  rc = btreeCursor
1fc90 4e 65 77 28 70 44 62 2c 20 70 4c 69 6e 6b 65 64  New(pDb, pLinked
1fca0 2c 20 26 70 43 73 72 2d 3e 70 42 74 43 73 72 29  , &pCsr->pBtCsr)
1fcb0 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
1fcc0 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 69 73 20  .    /* If this 
1fcd0 77 69 6c 6c 20 62 65 20 74 68 65 20 6f 6e 6c 79  will be the only
1fce0 20 73 65 67 6d 65 6e 74 20 69 6e 20 74 68 65 20   segment in the 
1fcf0 64 61 74 61 62 61 73 65 2c 20 64 69 73 63 61 72  database, discar
1fd00 64 20 61 6e 79 20 64 65 6c 65 74 65 0a 20 20 20  d any delete.   
1fd10 20 2a 2a 20 6d 61 72 6b 65 72 73 20 70 72 65 73   ** markers pres
1fd20 65 6e 74 20 69 6e 20 74 68 65 20 69 6e 2d 6d 65  ent in the in-me
1fd30 6d 6f 72 79 20 74 72 65 65 2e 20 20 2a 2f 0a 20  mory tree.  */. 
1fd40 20 20 20 69 66 28 20 70 4e 65 78 74 3d 3d 30 20     if( pNext==0 
1fd50 29 7b 0a 20 20 20 20 20 20 6d 75 6c 74 69 43 75  ){.      multiCu
1fd60 72 73 6f 72 49 67 6e 6f 72 65 44 65 6c 65 74 65  rsorIgnoreDelete
1fd70 28 70 43 73 72 29 3b 0a 20 20 20 20 7d 0a 20 20  (pCsr);.    }.  
1fd80 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 4c 53 4d  }..  if( rc!=LSM
1fd90 5f 4f 4b 20 29 7b 0a 20 20 20 20 6c 73 6d 4d 43  _OK ){.    lsmMC
1fda0 75 72 73 6f 72 43 6c 6f 73 65 28 70 43 73 72 2c  ursorClose(pCsr,
1fdb0 20 30 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20   0);.  }else{.  
1fdc0 20 20 4c 73 6d 50 67 6e 6f 20 69 4c 65 66 74 50    LsmPgno iLeftP
1fdd0 74 72 20 3d 20 30 3b 0a 20 20 20 20 4d 65 72 67  tr = 0;.    Merg
1fde0 65 20 6d 65 72 67 65 3b 20 20 20 20 20 20 20 20  e merge;        
1fdf0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 72            /* Mer
1fe00 67 65 20 6f 62 6a 65 63 74 20 75 73 65 64 20 74  ge object used t
1fe10 6f 20 63 72 65 61 74 65 20 6e 65 77 20 6c 65 76  o create new lev
1fe20 65 6c 20 2a 2f 0a 20 20 20 20 4d 65 72 67 65 57  el */.    MergeW
1fe30 6f 72 6b 65 72 20 6d 65 72 67 65 77 6f 72 6b 65  orker mergeworke
1fe40 72 3b 20 20 20 20 20 20 2f 2a 20 4d 65 72 67 65  r;      /* Merge
1fe50 57 6f 72 6b 65 72 20 6f 62 6a 65 63 74 20 66 6f  Worker object fo
1fe60 72 20 74 68 65 20 73 61 6d 65 20 70 75 72 70 6f  r the same purpo
1fe70 73 65 20 2a 2f 0a 0a 20 20 20 20 6d 65 6d 73 65  se */..    memse
1fe80 74 28 26 6d 65 72 67 65 2c 20 30 2c 20 73 69 7a  t(&merge, 0, siz
1fe90 65 6f 66 28 4d 65 72 67 65 29 29 3b 0a 20 20 20  eof(Merge));.   
1fea0 20 6d 65 6d 73 65 74 28 26 6d 65 72 67 65 77 6f   memset(&mergewo
1feb0 72 6b 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  rker, 0, sizeof(
1fec0 4d 65 72 67 65 57 6f 72 6b 65 72 29 29 3b 0a 0a  MergeWorker));..
1fed0 20 20 20 20 70 4e 65 77 2d 3e 70 4d 65 72 67 65      pNew->pMerge
1fee0 20 3d 20 26 6d 65 72 67 65 3b 0a 20 20 20 20 70   = &merge;.    p
1fef0 4e 65 77 2d 3e 66 6c 61 67 73 20 7c 3d 20 4c 45  New->flags |= LE
1ff00 56 45 4c 5f 49 4e 43 4f 4d 50 4c 45 54 45 3b 0a  VEL_INCOMPLETE;.
1ff10 20 20 20 20 6d 65 72 67 65 77 6f 72 6b 65 72 2e      mergeworker.
1ff20 70 44 62 20 3d 20 70 44 62 3b 0a 20 20 20 20 6d  pDb = pDb;.    m
1ff30 65 72 67 65 77 6f 72 6b 65 72 2e 70 4c 65 76 65  ergeworker.pLeve
1ff40 6c 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20 6d 65  l = pNew;.    me
1ff50 72 67 65 77 6f 72 6b 65 72 2e 70 43 73 72 20 3d  rgeworker.pCsr =
1ff60 20 70 43 73 72 3b 0a 20 20 20 20 70 43 73 72 2d   pCsr;.    pCsr-
1ff70 3e 70 50 72 65 76 4d 65 72 67 65 50 74 72 20 3d  >pPrevMergePtr =
1ff80 20 26 69 4c 65 66 74 50 74 72 3b 0a 0a 20 20 20   &iLeftPtr;..   
1ff90 20 2f 2a 20 4d 61 72 6b 20 74 68 65 20 73 65 70   /* Mark the sep
1ffa0 61 72 61 74 6f 72 73 20 61 72 72 61 79 20 66 6f  arators array fo
1ffb0 72 20 74 68 65 20 6e 65 77 20 6c 65 76 65 6c 20  r the new level 
1ffc0 61 73 20 61 20 22 70 68 61 6e 74 6f 6d 22 2e 20  as a "phantom". 
1ffd0 2a 2f 0a 20 20 20 20 6d 65 72 67 65 77 6f 72 6b  */.    mergework
1ffe0 65 72 2e 62 46 6c 75 73 68 20 3d 20 31 3b 0a 0a  er.bFlush = 1;..
1fff0 20 20 20 20 2f 2a 20 44 6f 20 74 68 65 20 77 6f      /* Do the wo
20000 72 6b 20 74 6f 20 63 72 65 61 74 65 20 74 68 65  rk to create the
20010 20 6e 65 77 20 6d 65 72 67 65 64 20 73 65 67 6d   new merged segm
20020 65 6e 74 20 6f 6e 20 64 69 73 6b 20 2a 2f 0a 20  ent on disk */. 
20030 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
20040 4b 20 29 20 72 63 20 3d 20 6c 73 6d 4d 43 75 72  K ) rc = lsmMCur
20050 73 6f 72 46 69 72 73 74 28 70 43 73 72 29 3b 0a  sorFirst(pCsr);.
20060 20 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 4c      while( rc==L
20070 53 4d 5f 4f 4b 20 26 26 20 6d 65 72 67 65 57 6f  SM_OK && mergeWo
20080 72 6b 65 72 44 6f 6e 65 28 26 6d 65 72 67 65 77  rkerDone(&mergew
20090 6f 72 6b 65 72 29 3d 3d 30 20 29 7b 0a 20 20 20  orker)==0 ){.   
200a0 20 20 20 72 63 20 3d 20 6d 65 72 67 65 57 6f 72     rc = mergeWor
200b0 6b 65 72 53 74 65 70 28 26 6d 65 72 67 65 77 6f  kerStep(&mergewo
200c0 72 6b 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 20  rker);.    }.   
200d0 20 6d 65 72 67 65 57 6f 72 6b 65 72 53 68 75 74   mergeWorkerShut
200e0 64 6f 77 6e 28 26 6d 65 72 67 65 77 6f 72 6b 65  down(&mergeworke
200f0 72 2c 20 26 72 63 29 3b 0a 20 20 20 20 61 73 73  r, &rc);.    ass
20100 65 72 74 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20  ert( rc!=LSM_OK 
20110 7c 7c 20 6d 65 72 67 65 77 6f 72 6b 65 72 2e 6e  || mergeworker.n
20120 57 6f 72 6b 3d 3d 30 20 7c 7c 20 70 4e 65 77 2d  Work==0 || pNew-
20130 3e 6c 68 73 2e 69 46 69 72 73 74 20 29 3b 0a 20  >lhs.iFirst );. 
20140 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
20150 4b 20 26 26 20 70 4e 65 77 2d 3e 6c 68 73 2e 69  K && pNew->lhs.i
20160 46 69 72 73 74 20 29 7b 0a 20 20 20 20 20 20 72  First ){.      r
20170 63 20 3d 20 6c 73 6d 46 73 53 6f 72 74 65 64 46  c = lsmFsSortedF
20180 69 6e 69 73 68 28 70 44 62 2d 3e 70 46 53 2c 20  inish(pDb->pFS, 
20190 26 70 4e 65 77 2d 3e 6c 68 73 29 3b 0a 20 20 20  &pNew->lhs);.   
201a0 20 7d 0a 20 20 20 20 6e 57 72 69 74 65 20 3d 20   }.    nWrite = 
201b0 6d 65 72 67 65 77 6f 72 6b 65 72 2e 6e 57 6f 72  mergeworker.nWor
201c0 6b 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 66 6c 61  k;.    pNew->fla
201d0 67 73 20 26 3d 20 7e 4c 45 56 45 4c 5f 49 4e 43  gs &= ~LEVEL_INC
201e0 4f 4d 50 4c 45 54 45 3b 0a 20 20 20 20 69 66 28  OMPLETE;.    if(
201f0 20 65 54 72 65 65 3d 3d 54 52 45 45 5f 4e 4f 4e   eTree==TREE_NON
20200 45 20 29 7b 0a 20 20 20 20 20 20 70 4e 65 77 2d  E ){.      pNew-
20210 3e 66 6c 61 67 73 20 7c 3d 20 4c 45 56 45 4c 5f  >flags |= LEVEL_
20220 46 52 45 45 4c 49 53 54 5f 4f 4e 4c 59 3b 0a 20  FREELIST_ONLY;. 
20230 20 20 20 7d 0a 20 20 20 20 70 4e 65 77 2d 3e 70     }.    pNew->p
20240 4d 65 72 67 65 20 3d 20 30 3b 0a 20 20 7d 0a 0a  Merge = 0;.  }..
20250 20 20 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b    if( rc!=LSM_OK
20260 20 7c 7c 20 70 4e 65 77 2d 3e 6c 68 73 2e 69 46   || pNew->lhs.iF
20270 69 72 73 74 3d 3d 30 20 29 7b 0a 20 20 20 20 61  irst==0 ){.    a
20280 73 73 65 72 74 28 20 72 63 21 3d 4c 53 4d 5f 4f  ssert( rc!=LSM_O
20290 4b 20 7c 7c 20 70 44 62 2d 3e 70 57 6f 72 6b 65  K || pDb->pWorke
202a0 72 2d 3e 66 72 65 65 6c 69 73 74 2e 6e 45 6e 74  r->freelist.nEnt
202b0 72 79 3d 3d 30 20 29 3b 0a 20 20 20 20 6c 73 6d  ry==0 );.    lsm
202c0 44 62 53 6e 61 70 73 68 6f 74 53 65 74 4c 65 76  DbSnapshotSetLev
202d0 65 6c 28 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2c  el(pDb->pWorker,
202e0 20 70 4e 65 78 74 29 3b 0a 20 20 20 20 73 6f 72   pNext);.    sor
202f0 74 65 64 46 72 65 65 4c 65 76 65 6c 28 70 44 62  tedFreeLevel(pDb
20300 2d 3e 70 45 6e 76 2c 20 70 4e 65 77 29 3b 0a 20  ->pEnv, pNew);. 
20310 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66 28 20   }else{.    if( 
20320 70 4c 69 6e 6b 65 64 20 29 7b 0a 20 20 20 20 20  pLinked ){.     
20330 20 70 4c 69 6e 6b 65 64 2d 3e 69 52 6f 6f 74 20   pLinked->iRoot 
20340 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  = 0;.    }else i
20350 66 28 20 70 44 65 6c 20 29 7b 0a 20 20 20 20 20  f( pDel ){.     
20360 20 61 73 73 65 72 74 28 20 70 4e 65 77 2d 3e 70   assert( pNew->p
20370 4e 65 78 74 3d 3d 70 44 65 6c 20 29 3b 0a 20 20  Next==pDel );.  
20380 20 20 20 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20      pNew->pNext 
20390 3d 20 70 44 65 6c 2d 3e 70 4e 65 78 74 3b 0a 20  = pDel->pNext;. 
203a0 20 20 20 20 20 6c 73 6d 46 73 53 6f 72 74 65 64       lsmFsSorted
203b0 44 65 6c 65 74 65 28 70 44 62 2d 3e 70 46 53 2c  Delete(pDb->pFS,
203c0 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2c 20 31   pDb->pWorker, 1
203d0 2c 20 26 70 44 65 6c 2d 3e 6c 68 73 29 3b 0a 20  , &pDel->lhs);. 
203e0 20 20 20 20 20 73 6f 72 74 65 64 46 72 65 65 4c       sortedFreeL
203f0 65 76 65 6c 28 70 44 62 2d 3e 70 45 6e 76 2c 20  evel(pDb->pEnv, 
20400 70 44 65 6c 29 3b 0a 20 20 20 20 7d 0a 0a 23 69  pDel);.    }..#i
20410 66 20 4c 53 4d 5f 4c 4f 47 5f 53 54 52 55 43 54  f LSM_LOG_STRUCT
20420 55 52 45 0a 20 20 20 20 6c 73 6d 53 6f 72 74 65  URE.    lsmSorte
20430 64 44 75 6d 70 53 74 72 75 63 74 75 72 65 28 70  dDumpStructure(p
20440 44 62 2c 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72  Db, pDb->pWorker
20450 2c 20 4c 53 4d 5f 4c 4f 47 5f 44 41 54 41 2c 20  , LSM_LOG_DATA, 
20460 30 2c 20 22 6e 65 77 2d 74 6f 70 6c 65 76 65 6c  0, "new-toplevel
20470 22 29 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 20 20  ");.#endif..    
20480 69 66 28 20 66 72 65 65 6c 69 73 74 2e 6e 45 6e  if( freelist.nEn
20490 74 72 79 20 29 7b 0a 20 20 20 20 20 20 46 72 65  try ){.      Fre
204a0 65 6c 69 73 74 20 2a 70 20 3d 20 26 70 44 62 2d  elist *p = &pDb-
204b0 3e 70 57 6f 72 6b 65 72 2d 3e 66 72 65 65 6c 69  >pWorker->freeli
204c0 73 74 3b 0a 20 20 20 20 20 20 6c 73 6d 46 72 65  st;.      lsmFre
204d0 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70 2d 3e  e(pDb->pEnv, p->
204e0 61 45 6e 74 72 79 29 3b 0a 20 20 20 20 20 20 6d  aEntry);.      m
204f0 65 6d 63 70 79 28 70 2c 20 26 66 72 65 65 6c 69  emcpy(p, &freeli
20500 73 74 2c 20 73 69 7a 65 6f 66 28 66 72 65 65 6c  st, sizeof(freel
20510 69 73 74 29 29 3b 0a 20 20 20 20 20 20 66 72 65  ist));.      fre
20520 65 6c 69 73 74 2e 61 45 6e 74 72 79 20 3d 20 30  elist.aEntry = 0
20530 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
20540 20 20 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2d     pDb->pWorker-
20550 3e 66 72 65 65 6c 69 73 74 2e 6e 45 6e 74 72 79  >freelist.nEntry
20560 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 0a 20 20 20   = 0;.    }..   
20570 20 61 73 73 65 72 74 42 74 72 65 65 4f 6b 28 70   assertBtreeOk(p
20580 44 62 2c 20 26 70 4e 65 77 2d 3e 6c 68 73 29 3b  Db, &pNew->lhs);
20590 0a 20 20 20 20 73 6f 72 74 65 64 49 6e 76 6f 6b  .    sortedInvok
205a0 65 57 6f 72 6b 48 6f 6f 6b 28 70 44 62 29 3b 0a  eWorkHook(pDb);.
205b0 20 20 7d 0a 0a 20 20 69 66 28 20 70 6e 57 72 69    }..  if( pnWri
205c0 74 65 20 29 20 2a 70 6e 57 72 69 74 65 20 3d 20  te ) *pnWrite = 
205d0 6e 57 72 69 74 65 3b 0a 20 20 70 44 62 2d 3e 70  nWrite;.  pDb->p
205e0 57 6f 72 6b 65 72 2d 3e 6e 57 72 69 74 65 20 2b  Worker->nWrite +
205f0 3d 20 6e 57 72 69 74 65 3b 0a 20 20 70 44 62 2d  = nWrite;.  pDb-
20600 3e 70 46 72 65 65 6c 69 73 74 20 3d 20 30 3b 0a  >pFreelist = 0;.
20610 20 20 70 44 62 2d 3e 62 55 73 65 46 72 65 65 6c    pDb->bUseFreel
20620 69 73 74 20 3d 20 30 3b 0a 20 20 6c 73 6d 46 72  ist = 0;.  lsmFr
20630 65 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 66 72  ee(pDb->pEnv, fr
20640 65 65 6c 69 73 74 2e 61 45 6e 74 72 79 29 3b 0a  eelist.aEntry);.
20650 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
20660 2f 2a 0a 2a 2a 20 54 68 65 20 6e 4d 65 72 67 65  /*.** The nMerge
20670 20 6c 65 76 65 6c 73 20 69 6e 20 74 68 65 20 4c   levels in the L
20680 53 4d 20 62 65 67 69 6e 6e 69 6e 67 20 77 69 74  SM beginning wit
20690 68 20 70 4c 65 76 65 6c 20 63 6f 6e 73 69 73 74  h pLevel consist
206a0 20 6f 66 20 61 0a 2a 2a 20 6c 65 66 74 2d 68 61   of a.** left-ha
206b0 6e 64 2d 73 69 64 65 20 73 65 67 6d 65 6e 74 20  nd-side segment 
206c0 6f 6e 6c 79 2e 20 52 65 70 6c 61 63 65 20 74 68  only. Replace th
206d0 65 73 65 20 6c 65 76 65 6c 73 20 77 69 74 68 20  ese levels with 
206e0 61 20 73 69 6e 67 6c 65 20 6e 65 77 0a 2a 2a 20  a single new.** 
206f0 6c 65 76 65 6c 20 63 6f 6e 73 69 73 74 69 6e 67  level consisting
20700 20 6f 66 20 61 20 6e 65 77 20 65 6d 70 74 79 20   of a new empty 
20710 73 65 67 6d 65 6e 74 20 6f 6e 20 74 68 65 20 6c  segment on the l
20720 65 66 74 2d 68 61 6e 64 2d 73 69 64 65 20 61 6e  eft-hand-side an
20730 64 20 74 68 65 0a 2a 2a 20 6e 4d 65 72 67 65 20  d the.** nMerge 
20740 73 65 67 6d 65 6e 74 73 20 66 72 6f 6d 20 74 68  segments from th
20750 65 20 72 65 70 6c 61 63 65 64 20 6c 65 76 65 6c  e replaced level
20760 73 20 6f 6e 20 74 68 65 20 72 69 67 68 74 2d 68  s on the right-h
20770 61 6e 64 2d 73 69 64 65 2e 0a 2a 2a 0a 2a 2a 20  and-side..**.** 
20780 41 6c 73 6f 2c 20 61 6c 6c 6f 63 61 74 65 20 61  Also, allocate a
20790 6e 64 20 70 6f 70 75 6c 61 74 65 20 61 20 4d 65  nd populate a Me
207a0 72 67 65 20 6f 62 6a 65 63 74 20 61 6e 64 20 73  rge object and s
207b0 65 74 20 4c 65 76 65 6c 2e 70 4d 65 72 67 65 20  et Level.pMerge 
207c0 74 6f 0a 2a 2a 20 70 6f 69 6e 74 20 74 6f 20 69  to.** point to i
207d0 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t..*/.static int
207e0 20 73 6f 72 74 65 64 4d 65 72 67 65 53 65 74 75   sortedMergeSetu
207f0 70 28 0a 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62  p(.  lsm_db *pDb
20800 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
20810 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
20820 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 4c 65 76   handle */.  Lev
20830 65 6c 20 2a 70 4c 65 76 65 6c 2c 20 20 20 20 20  el *pLevel,     
20840 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
20850 46 69 72 73 74 20 6c 65 76 65 6c 20 74 6f 20 6d  First level to m
20860 65 72 67 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d  erge */.  int nM
20870 65 72 67 65 2c 20 20 20 20 20 20 20 20 20 20 20  erge,           
20880 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 65 72            /* Mer
20890 67 65 20 74 68 69 73 20 6d 61 6e 79 20 6c 65 76  ge this many lev
208a0 65 6c 73 20 74 6f 67 65 74 68 65 72 20 2a 2f 0a  els together */.
208b0 20 20 4c 65 76 65 6c 20 2a 2a 70 70 4e 65 77 20    Level **ppNew 
208c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
208d0 20 20 2f 2a 20 4e 65 77 2c 20 6d 65 72 67 65 64    /* New, merged
208e0 2c 20 6c 65 76 65 6c 20 2a 2f 0a 29 7b 0a 20 20  , level */.){.  
208f0 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b  int rc = LSM_OK;
20900 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20910 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a  /* Return Code *
20920 2f 0a 20 20 4c 65 76 65 6c 20 2a 70 4e 65 77 3b  /.  Level *pNew;
20930 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20940 20 20 20 20 2f 2a 20 4e 65 77 20 4c 65 76 65 6c      /* New Level
20950 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74   object */.  int
20960 20 62 55 73 65 4e 65 78 74 20 3d 20 30 3b 20 20   bUseNext = 0;  
20970 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
20980 54 72 75 65 20 74 6f 20 6c 69 6e 6b 20 69 6e 20  True to link in 
20990 6e 65 78 74 20 73 65 70 61 72 61 74 6f 72 73 20  next separators 
209a0 2a 2f 0a 20 20 4d 65 72 67 65 20 2a 70 4d 65 72  */.  Merge *pMer
209b0 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
209c0 20 20 20 20 20 2f 2a 20 4e 65 77 20 4d 65 72 67       /* New Merg
209d0 65 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e  e object */.  in
209e0 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20  t nByte;        
209f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
20a00 20 42 79 74 65 73 20 6f 66 20 73 70 61 63 65 20   Bytes of space 
20a10 61 6c 6c 6f 63 61 74 65 64 20 61 74 20 70 4d 65  allocated at pMe
20a20 72 67 65 20 2a 2f 0a 0a 23 69 66 64 65 66 20 4c  rge */..#ifdef L
20a30 53 4d 5f 44 45 42 55 47 0a 20 20 69 6e 74 20 69  SM_DEBUG.  int i
20a40 4c 65 76 65 6c 3b 0a 20 20 4c 65 76 65 6c 20 2a  Level;.  Level *
20a50 70 58 20 3d 20 70 4c 65 76 65 6c 3b 0a 20 20 66  pX = pLevel;.  f
20a60 6f 72 28 69 4c 65 76 65 6c 3d 30 3b 20 69 4c 65  or(iLevel=0; iLe
20a70 76 65 6c 3c 6e 4d 65 72 67 65 3b 20 69 4c 65 76  vel<nMerge; iLev
20a80 65 6c 2b 2b 29 7b 0a 20 20 20 20 61 73 73 65 72  el++){.    asser
20a90 74 28 20 70 58 2d 3e 6e 52 69 67 68 74 3d 3d 30  t( pX->nRight==0
20aa0 20 29 3b 0a 20 20 20 20 70 58 20 3d 20 70 58 2d   );.    pX = pX-
20ab0 3e 70 4e 65 78 74 3b 0a 20 20 7d 0a 23 65 6e 64  >pNext;.  }.#end
20ac0 69 66 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  if..  /* Allocat
20ad0 65 20 74 68 65 20 6e 65 77 20 4c 65 76 65 6c 20  e the new Level 
20ae0 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 70 4e 65 77  object */.  pNew
20af0 20 3d 20 28 4c 65 76 65 6c 20 2a 29 6c 73 6d 4d   = (Level *)lsmM
20b00 61 6c 6c 6f 63 5a 65 72 6f 52 63 28 70 44 62 2d  allocZeroRc(pDb-
20b10 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66 28 4c 65  >pEnv, sizeof(Le
20b20 76 65 6c 29 2c 20 26 72 63 29 3b 0a 20 20 69 66  vel), &rc);.  if
20b30 28 20 70 4e 65 77 20 29 7b 0a 20 20 20 20 70 4e  ( pNew ){.    pN
20b40 65 77 2d 3e 61 52 68 73 20 3d 20 28 53 65 67 6d  ew->aRhs = (Segm
20b50 65 6e 74 20 2a 29 6c 73 6d 4d 61 6c 6c 6f 63 5a  ent *)lsmMallocZ
20b60 65 72 6f 52 63 28 70 44 62 2d 3e 70 45 6e 76 2c  eroRc(pDb->pEnv,
20b70 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   .              
20b80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20b90 20 20 20 20 20 20 20 20 20 20 6e 4d 65 72 67 65            nMerge
20ba0 20 2a 20 73 69 7a 65 6f 66 28 53 65 67 6d 65 6e   * sizeof(Segmen
20bb0 74 29 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20  t), &rc);.  }.. 
20bc0 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20 74 68 65   /* Populate the
20bd0 20 6e 65 77 20 4c 65 76 65 6c 20 6f 62 6a 65 63   new Level objec
20be0 74 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 4c  t */.  if( rc==L
20bf0 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 4c 65 76  SM_OK ){.    Lev
20c00 65 6c 20 2a 70 4e 65 78 74 20 3d 20 30 3b 20 20  el *pNext = 0;  
20c10 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 65             /* Le
20c20 76 65 6c 20 66 6f 6c 6c 6f 77 69 6e 67 20 70 4e  vel following pN
20c30 65 77 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 3b  ew */.    int i;
20c40 0a 20 20 20 20 69 6e 74 20 62 46 72 65 65 4f 6e  .    int bFreeOn
20c50 6c 79 20 3d 20 31 3b 0a 20 20 20 20 4c 65 76 65  ly = 1;.    Leve
20c60 6c 20 2a 70 54 6f 70 4c 65 76 65 6c 3b 0a 20 20  l *pTopLevel;.  
20c70 20 20 4c 65 76 65 6c 20 2a 70 20 3d 20 70 4c 65    Level *p = pLe
20c80 76 65 6c 3b 0a 20 20 20 20 4c 65 76 65 6c 20 2a  vel;.    Level *
20c90 2a 70 70 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 6e  *pp;.    pNew->n
20ca0 52 69 67 68 74 20 3d 20 6e 4d 65 72 67 65 3b 0a  Right = nMerge;.
20cb0 20 20 20 20 70 4e 65 77 2d 3e 69 41 67 65 20 3d      pNew->iAge =
20cc0 20 70 4c 65 76 65 6c 2d 3e 69 41 67 65 2b 31 3b   pLevel->iAge+1;
20cd0 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  .    for(i=0; i<
20ce0 6e 4d 65 72 67 65 3b 20 69 2b 2b 29 7b 0a 20 20  nMerge; i++){.  
20cf0 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e      assert( p->n
20d00 52 69 67 68 74 3d 3d 30 20 29 3b 0a 20 20 20 20  Right==0 );.    
20d10 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 70 4e 65    pNext = p->pNe
20d20 78 74 3b 0a 20 20 20 20 20 20 70 4e 65 77 2d 3e  xt;.      pNew->
20d30 61 52 68 73 5b 69 5d 20 3d 20 70 2d 3e 6c 68 73  aRhs[i] = p->lhs
20d40 3b 0a 20 20 20 20 20 20 69 66 28 20 28 70 2d 3e  ;.      if( (p->
20d50 66 6c 61 67 73 20 26 20 4c 45 56 45 4c 5f 46 52  flags & LEVEL_FR
20d60 45 45 4c 49 53 54 5f 4f 4e 4c 59 29 3d 3d 30 20  EELIST_ONLY)==0 
20d70 29 20 62 46 72 65 65 4f 6e 6c 79 20 3d 20 30 3b  ) bFreeOnly = 0;
20d80 0a 20 20 20 20 20 20 73 6f 72 74 65 64 46 72 65  .      sortedFre
20d90 65 4c 65 76 65 6c 28 70 44 62 2d 3e 70 45 6e 76  eLevel(pDb->pEnv
20da0 2c 20 70 29 3b 0a 20 20 20 20 20 20 70 20 3d 20  , p);.      p = 
20db0 70 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 0a 20 20  pNext;.    }..  
20dc0 20 20 69 66 28 20 62 46 72 65 65 4f 6e 6c 79 20    if( bFreeOnly 
20dd0 29 20 70 4e 65 77 2d 3e 66 6c 61 67 73 20 7c 3d  ) pNew->flags |=
20de0 20 4c 45 56 45 4c 5f 46 52 45 45 4c 49 53 54 5f   LEVEL_FREELIST_
20df0 4f 4e 4c 59 3b 0a 0a 20 20 20 20 2f 2a 20 52 65  ONLY;..    /* Re
20e00 70 6c 61 63 65 20 74 68 65 20 6f 6c 64 20 6c 65  place the old le
20e10 76 65 6c 73 20 77 69 74 68 20 74 68 65 20 6e 65  vels with the ne
20e20 77 2e 20 2a 2f 0a 20 20 20 20 70 54 6f 70 4c 65  w. */.    pTopLe
20e30 76 65 6c 20 3d 20 6c 73 6d 44 62 53 6e 61 70 73  vel = lsmDbSnaps
20e40 68 6f 74 4c 65 76 65 6c 28 70 44 62 2d 3e 70 57  hotLevel(pDb->pW
20e50 6f 72 6b 65 72 29 3b 0a 20 20 20 20 70 4e 65 77  orker);.    pNew
20e60 2d 3e 70 4e 65 78 74 20 3d 20 70 3b 0a 20 20 20  ->pNext = p;.   
20e70 20 66 6f 72 28 70 70 3d 26 70 54 6f 70 4c 65 76   for(pp=&pTopLev
20e80 65 6c 3b 20 2a 70 70 21 3d 70 4c 65 76 65 6c 3b  el; *pp!=pLevel;
20e90 20 70 70 3d 26 28 28 2a 70 70 29 2d 3e 70 4e 65   pp=&((*pp)->pNe
20ea0 78 74 29 29 3b 0a 20 20 20 20 2a 70 70 20 3d 20  xt));.    *pp = 
20eb0 70 4e 65 77 3b 0a 20 20 20 20 6c 73 6d 44 62 53  pNew;.    lsmDbS
20ec0 6e 61 70 73 68 6f 74 53 65 74 4c 65 76 65 6c 28  napshotSetLevel(
20ed0 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2c 20 70 54  pDb->pWorker, pT
20ee0 6f 70 4c 65 76 65 6c 29 3b 0a 0a 20 20 20 20 2f  opLevel);..    /
20ef0 2a 20 44 65 74 65 72 6d 69 6e 65 20 77 68 65 74  * Determine whet
20f00 68 65 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 6e  her or not the n
20f10 65 78 74 20 73 65 70 61 72 61 74 6f 72 73 20 77  ext separators w
20f20 69 6c 6c 20 62 65 20 6c 69 6e 6b 65 64 20 69 6e  ill be linked in
20f30 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 4e 65 78   */.    if( pNex
20f40 74 20 26 26 20 70 4e 65 78 74 2d 3e 70 4d 65 72  t && pNext->pMer
20f50 67 65 3d 3d 30 20 26 26 20 70 4e 65 78 74 2d 3e  ge==0 && pNext->
20f60 6c 68 73 2e 69 52 6f 6f 74 20 26 26 20 70 4e 65  lhs.iRoot && pNe
20f70 78 74 20 0a 20 20 20 20 20 26 26 20 28 62 46 72  xt .     && (bFr
20f80 65 65 4f 6e 6c 79 3d 3d 30 20 7c 7c 20 28 70 4e  eeOnly==0 || (pN
20f90 65 78 74 2d 3e 66 6c 61 67 73 20 26 20 4c 45 56  ext->flags & LEV
20fa0 45 4c 5f 46 52 45 45 4c 49 53 54 5f 4f 4e 4c 59  EL_FREELIST_ONLY
20fb0 29 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20  )).    ){.      
20fc0 62 55 73 65 4e 65 78 74 20 3d 20 31 3b 0a 20 20  bUseNext = 1;.  
20fd0 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 6c    }.  }..  /* Al
20fe0 6c 6f 63 61 74 65 20 74 68 65 20 6d 65 72 67 65  locate the merge
20ff0 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 6e 42 79   object */.  nBy
21000 74 65 20 3d 20 73 69 7a 65 6f 66 28 4d 65 72 67  te = sizeof(Merg
21010 65 29 20 2b 20 73 69 7a 65 6f 66 28 4d 65 72 67  e) + sizeof(Merg
21020 65 49 6e 70 75 74 29 20 2a 20 28 6e 4d 65 72 67  eInput) * (nMerg
21030 65 20 2b 20 62 55 73 65 4e 65 78 74 29 3b 0a 20  e + bUseNext);. 
21040 20 70 4d 65 72 67 65 20 3d 20 28 4d 65 72 67 65   pMerge = (Merge
21050 20 2a 29 6c 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f   *)lsmMallocZero
21060 52 63 28 70 44 62 2d 3e 70 45 6e 76 2c 20 6e 42  Rc(pDb->pEnv, nB
21070 79 74 65 2c 20 26 72 63 29 3b 0a 20 20 69 66 28  yte, &rc);.  if(
21080 20 70 4d 65 72 67 65 20 29 7b 0a 20 20 20 20 70   pMerge ){.    p
21090 4d 65 72 67 65 2d 3e 61 49 6e 70 75 74 20 3d 20  Merge->aInput = 
210a0 28 4d 65 72 67 65 49 6e 70 75 74 20 2a 29 26 70  (MergeInput *)&p
210b0 4d 65 72 67 65 5b 31 5d 3b 0a 20 20 20 20 70 4d  Merge[1];.    pM
210c0 65 72 67 65 2d 3e 6e 49 6e 70 75 74 20 3d 20 6e  erge->nInput = n
210d0 4d 65 72 67 65 20 2b 20 62 55 73 65 4e 65 78 74  Merge + bUseNext
210e0 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 70 4d 65 72  ;.    pNew->pMer
210f0 67 65 20 3d 20 70 4d 65 72 67 65 3b 0a 20 20 7d  ge = pMerge;.  }
21100 0a 0a 20 20 2a 70 70 4e 65 77 20 3d 20 70 4e 65  ..  *ppNew = pNe
21110 77 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  w;.  return rc;.
21120 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65  }..static int me
21130 72 67 65 57 6f 72 6b 65 72 49 6e 69 74 28 0a 20  rgeWorkerInit(. 
21140 20 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20   lsm_db *pDb,   
21150 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21160 20 2f 2a 20 44 62 20 63 6f 6e 6e 65 63 74 69 6f   /* Db connectio
21170 6e 20 74 6f 20 64 6f 20 6d 65 72 67 65 20 77 6f  n to do merge wo
21180 72 6b 20 2a 2f 0a 20 20 4c 65 76 65 6c 20 2a 70  rk */.  Level *p
21190 4c 65 76 65 6c 2c 20 20 20 20 20 20 20 20 20 20  Level,          
211a0 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 76 65 6c          /* Level
211b0 20 74 6f 20 77 6f 72 6b 20 6f 6e 20 6d 65 72 67   to work on merg
211c0 69 6e 67 20 2a 2f 0a 20 20 4d 65 72 67 65 57 6f  ing */.  MergeWo
211d0 72 6b 65 72 20 2a 70 4d 57 20 20 20 20 20 20 20  rker *pMW       
211e0 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65           /* Obje
211f0 63 74 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  ct to initialize
21200 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20   */.){.  int rc 
21210 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20  = LSM_OK;       
21220 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
21230 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 4d 65 72  rn code */.  Mer
21240 67 65 20 2a 70 4d 65 72 67 65 20 3d 20 70 4c 65  ge *pMerge = pLe
21250 76 65 6c 2d 3e 70 4d 65 72 67 65 3b 20 2f 2a 20  vel->pMerge; /* 
21260 50 65 72 73 69 73 74 65 6e 74 20 70 61 72 74 20  Persistent part 
21270 6f 66 20 6d 65 72 67 65 20 73 74 61 74 65 20 2a  of merge state *
21280 2f 0a 20 20 4d 75 6c 74 69 43 75 72 73 6f 72 20  /.  MultiCursor 
21290 2a 70 43 73 72 20 3d 20 30 3b 20 20 20 20 20 20  *pCsr = 0;      
212a0 20 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 6f 70      /* Cursor op
212b0 65 6e 65 64 20 66 6f 72 20 70 4d 57 20 2a 2f 0a  ened for pMW */.
212c0 20 20 4c 65 76 65 6c 20 2a 70 4e 65 78 74 20 3d    Level *pNext =
212d0 20 70 4c 65 76 65 6c 2d 3e 70 4e 65 78 74 3b 20   pLevel->pNext; 
212e0 20 20 2f 2a 20 4e 65 78 74 20 6c 65 76 65 6c 20    /* Next level 
212f0 69 6e 20 4c 53 4d 20 2a 2f 0a 0a 20 20 61 73 73  in LSM */..  ass
21300 65 72 74 28 20 70 44 62 2d 3e 70 57 6f 72 6b 65  ert( pDb->pWorke
21310 72 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  r );.  assert( p
21320 4c 65 76 65 6c 2d 3e 70 4d 65 72 67 65 20 29 3b  Level->pMerge );
21330 0a 20 20 61 73 73 65 72 74 28 20 70 4c 65 76 65  .  assert( pLeve
21340 6c 2d 3e 6e 52 69 67 68 74 3e 30 20 29 3b 0a 0a  l->nRight>0 );..
21350 20 20 6d 65 6d 73 65 74 28 70 4d 57 2c 20 30 2c    memset(pMW, 0,
21360 20 73 69 7a 65 6f 66 28 4d 65 72 67 65 57 6f 72   sizeof(MergeWor
21370 6b 65 72 29 29 3b 0a 20 20 70 4d 57 2d 3e 70 44  ker));.  pMW->pD
21380 62 20 3d 20 70 44 62 3b 0a 20 20 70 4d 57 2d 3e  b = pDb;.  pMW->
21390 70 4c 65 76 65 6c 20 3d 20 70 4c 65 76 65 6c 3b  pLevel = pLevel;
213a0 0a 20 20 70 4d 57 2d 3e 61 47 6f 62 62 6c 65 20  .  pMW->aGobble 
213b0 3d 20 6c 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52  = lsmMallocZeroR
213c0 63 28 70 44 62 2d 3e 70 45 6e 76 2c 20 73 69 7a  c(pDb->pEnv, siz
213d0 65 6f 66 28 4c 73 6d 50 67 6e 6f 29 2a 70 4c 65  eof(LsmPgno)*pLe
213e0 76 65 6c 2d 3e 6e 52 69 67 68 74 2c 26 72 63 29  vel->nRight,&rc)
213f0 3b 0a 0a 20 20 2f 2a 20 43 72 65 61 74 65 20 61  ;..  /* Create a
21400 20 6d 75 6c 74 69 2d 63 75 72 73 6f 72 20 74 6f   multi-cursor to
21410 20 72 65 61 64 20 74 68 65 20 64 61 74 61 20 74   read the data t
21420 6f 20 77 72 69 74 65 20 74 6f 20 74 68 65 20 6e  o write to the n
21430 65 77 0a 20 20 2a 2a 20 73 65 67 6d 65 6e 74 2e  ew.  ** segment.
21440 20 54 68 65 20 6e 65 77 20 73 65 67 6d 65 6e 74   The new segment
21450 20 63 6f 6e 74 61 69 6e 73 3a 0a 20 20 2a 2a 0a   contains:.  **.
21460 20 20 2a 2a 20 20 20 31 2e 20 52 65 63 6f 72 64    **   1. Record
21470 73 20 66 72 6f 6d 20 4c 48 53 20 6f 66 20 65 61  s from LHS of ea
21480 63 68 20 6f 66 20 74 68 65 20 6e 4d 65 72 67 65  ch of the nMerge
21490 20 6c 65 76 65 6c 73 20 62 65 69 6e 67 20 6d 65   levels being me
214a0 72 67 65 64 2e 0a 20 20 2a 2a 20 20 20 32 2e 20  rged..  **   2. 
214b0 53 65 70 61 72 61 74 6f 72 73 20 66 72 6f 6d 20  Separators from 
214c0 65 69 74 68 65 72 20 74 68 65 20 6c 61 73 74 20  either the last 
214d0 6c 65 76 65 6c 20 62 65 69 6e 67 20 6d 65 72 67  level being merg
214e0 65 64 2c 20 6f 72 20 74 68 65 0a 20 20 2a 2a 20  ed, or the.  ** 
214f0 20 20 20 20 20 73 65 70 61 72 61 74 6f 72 73 20       separators 
21500 61 74 74 61 63 68 65 64 20 74 6f 20 74 68 65 20  attached to the 
21510 4c 48 53 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  LHS of the follo
21520 77 69 6e 67 20 6c 65 76 65 6c 2c 20 6f 72 20 6e  wing level, or n
21530 65 69 74 68 65 72 2e 0a 20 20 2a 2a 0a 20 20 2a  either..  **.  *
21540 2a 20 49 66 20 74 68 65 20 6e 65 77 20 6c 65 76  * If the new lev
21550 65 6c 20 69 73 20 74 68 65 20 6c 6f 77 65 73 74  el is the lowest
21560 20 28 6f 6c 64 65 73 74 29 20 69 6e 20 74 68 65   (oldest) in the
21570 20 64 62 2c 20 64 69 73 63 61 72 64 20 61 6e 79   db, discard any
21580 0a 20 20 2a 2a 20 64 65 6c 65 74 65 20 6b 65 79  .  ** delete key
21590 73 2e 20 4b 65 79 20 61 6e 6e 69 68 69 6c 61 74  s. Key annihilat
215a0 69 6f 6e 2e 0a 20 20 2a 2f 0a 20 20 70 43 73 72  ion..  */.  pCsr
215b0 20 3d 20 6d 75 6c 74 69 43 75 72 73 6f 72 4e 65   = multiCursorNe
215c0 77 28 70 44 62 2c 20 26 72 63 29 3b 0a 20 20 69  w(pDb, &rc);.  i
215d0 66 28 20 70 43 73 72 20 29 7b 0a 20 20 20 20 70  f( pCsr ){.    p
215e0 43 73 72 2d 3e 66 6c 61 67 73 20 7c 3d 20 43 55  Csr->flags |= CU
215f0 52 53 4f 52 5f 4e 45 58 54 5f 4f 4b 3b 0a 20 20  RSOR_NEXT_OK;.  
21600 20 20 72 63 20 3d 20 6d 75 6c 74 69 43 75 72 73    rc = multiCurs
21610 6f 72 41 64 64 52 68 73 28 70 43 73 72 2c 20 70  orAddRhs(pCsr, p
21620 4c 65 76 65 6c 29 3b 0a 20 20 7d 0a 20 20 69 66  Level);.  }.  if
21630 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20  ( rc==LSM_OK && 
21640 70 4d 65 72 67 65 2d 3e 6e 49 6e 70 75 74 20 3e  pMerge->nInput >
21650 20 70 4c 65 76 65 6c 2d 3e 6e 52 69 67 68 74 20   pLevel->nRight 
21660 29 7b 0a 20 20 20 20 72 63 20 3d 20 62 74 72 65  ){.    rc = btre
21670 65 43 75 72 73 6f 72 4e 65 77 28 70 44 62 2c 20  eCursorNew(pDb, 
21680 26 70 4e 65 78 74 2d 3e 6c 68 73 2c 20 26 70 43  &pNext->lhs, &pC
21690 73 72 2d 3e 70 42 74 43 73 72 29 3b 0a 20 20 7d  sr->pBtCsr);.  }
216a0 65 6c 73 65 20 69 66 28 20 70 4e 65 78 74 20 29  else if( pNext )
216b0 7b 0a 20 20 20 20 6d 75 6c 74 69 43 75 72 73 6f  {.    multiCurso
216c0 72 52 65 61 64 53 65 70 61 72 61 74 6f 72 73 28  rReadSeparators(
216d0 70 43 73 72 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  pCsr);.  }else{.
216e0 20 20 20 20 6d 75 6c 74 69 43 75 72 73 6f 72 49      multiCursorI
216f0 67 6e 6f 72 65 44 65 6c 65 74 65 28 70 43 73 72  gnoreDelete(pCsr
21700 29 3b 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74  );.  }..  assert
21710 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20  ( rc!=LSM_OK || 
21720 70 4d 65 72 67 65 2d 3e 6e 49 6e 70 75 74 3d 3d  pMerge->nInput==
21730 28 70 43 73 72 2d 3e 6e 50 74 72 2b 28 70 43 73  (pCsr->nPtr+(pCs
21740 72 2d 3e 70 42 74 43 73 72 21 3d 30 29 29 20 29  r->pBtCsr!=0)) )
21750 3b 0a 20 20 70 4d 57 2d 3e 70 43 73 72 20 3d 20  ;.  pMW->pCsr = 
21760 70 43 73 72 3b 0a 0a 20 20 2f 2a 20 4c 6f 61 64  pCsr;..  /* Load
21770 20 74 68 65 20 62 2d 74 72 65 65 20 68 69 65 72   the b-tree hier
21780 61 72 63 68 79 20 69 6e 74 6f 20 6d 65 6d 6f 72  archy into memor
21790 79 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d  y. */.  if( rc==
217a0 4c 53 4d 5f 4f 4b 20 29 20 72 63 20 3d 20 6d 65  LSM_OK ) rc = me
217b0 72 67 65 57 6f 72 6b 65 72 4c 6f 61 64 48 69 65  rgeWorkerLoadHie
217c0 72 61 72 63 68 79 28 70 4d 57 29 3b 0a 20 20 69  rarchy(pMW);.  i
217d0 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26  f( rc==LSM_OK &&
217e0 20 70 4d 57 2d 3e 68 69 65 72 2e 6e 48 69 65 72   pMW->hier.nHier
217f0 3d 3d 30 20 29 7b 0a 20 20 20 20 70 4d 57 2d 3e  ==0 ){.    pMW->
21800 61 53 61 76 65 5b 30 5d 2e 69 50 67 6e 6f 20 3d  aSave[0].iPgno =
21810 20 70 4c 65 76 65 6c 2d 3e 6c 68 73 2e 69 46 69   pLevel->lhs.iFi
21820 72 73 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 50  rst;.  }..  /* P
21830 6f 73 69 74 69 6f 6e 20 74 68 65 20 63 75 72 73  osition the curs
21840 6f 72 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d  or. */.  if( rc=
21850 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 70  =LSM_OK ){.    p
21860 43 73 72 2d 3e 70 50 72 65 76 4d 65 72 67 65 50  Csr->pPrevMergeP
21870 74 72 20 3d 20 26 70 4d 65 72 67 65 2d 3e 69 43  tr = &pMerge->iC
21880 75 72 72 65 6e 74 50 74 72 3b 0a 20 20 20 20 69  urrentPtr;.    i
21890 66 28 20 70 4c 65 76 65 6c 2d 3e 6c 68 73 2e 69  f( pLevel->lhs.i
218a0 46 69 72 73 74 3d 3d 30 20 29 7b 0a 20 20 20 20  First==0 ){.    
218b0 20 20 2f 2a 20 54 68 65 20 6f 75 74 70 75 74 20    /* The output 
218c0 61 72 72 61 79 20 69 73 20 73 74 69 6c 6c 20 65  array is still e
218d0 6d 70 74 79 2e 20 53 6f 20 70 6f 73 69 74 69 6f  mpty. So positio
218e0 6e 20 74 68 65 20 63 75 72 73 6f 72 20 61 74 20  n the cursor at 
218f0 74 68 65 20 76 65 72 79 20 0a 20 20 20 20 20 20  the very .      
21900 2a 2a 20 73 74 61 72 74 20 6f 66 20 74 68 65 20  ** start of the 
21910 69 6e 70 75 74 2e 20 20 2a 2f 0a 20 20 20 20 20  input.  */.     
21920 20 72 63 20 3d 20 6d 75 6c 74 69 43 75 72 73 6f   rc = multiCurso
21930 72 45 6e 64 28 70 43 73 72 2c 20 30 29 3b 0a 20  rEnd(pCsr, 0);. 
21940 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
21950 2f 2a 20 54 68 65 20 6f 75 74 70 75 74 20 61 72  /* The output ar
21960 72 61 79 20 69 73 20 6e 6f 6e 2d 65 6d 70 74 79  ray is non-empty
21970 2e 20 50 6f 73 69 74 69 6f 6e 20 74 68 65 20 63  . Position the c
21980 75 72 73 6f 72 20 62 61 73 65 64 20 6f 6e 20 74  ursor based on t
21990 68 65 0a 20 20 20 20 20 20 2a 2a 20 70 61 67 65  he.      ** page
219a0 2f 63 65 6c 6c 20 64 61 74 61 20 73 61 76 65 64  /cell data saved
219b0 20 69 6e 20 74 68 65 20 4d 65 72 67 65 2e 61 49   in the Merge.aI
219c0 6e 70 75 74 5b 5d 20 61 72 72 61 79 2e 20 20 2a  nput[] array.  *
219d0 2f 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20  /.      int i;. 
219e0 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63       for(i=0; rc
219f0 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 69 3c 70 43  ==LSM_OK && i<pC
21a00 73 72 2d 3e 6e 50 74 72 3b 20 69 2b 2b 29 7b 0a  sr->nPtr; i++){.
21a10 20 20 20 20 20 20 20 20 4d 65 72 67 65 49 6e 70          MergeInp
21a20 75 74 20 2a 70 49 6e 70 75 74 20 3d 20 26 70 4d  ut *pInput = &pM
21a30 65 72 67 65 2d 3e 61 49 6e 70 75 74 5b 69 5d 3b  erge->aInput[i];
21a40 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 49 6e  .        if( pIn
21a50 70 75 74 2d 3e 69 50 67 20 29 7b 0a 20 20 20 20  put->iPg ){.    
21a60 20 20 20 20 20 20 53 65 67 6d 65 6e 74 50 74 72        SegmentPtr
21a70 20 2a 70 50 74 72 3b 0a 20 20 20 20 20 20 20 20   *pPtr;.        
21a80 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
21a90 61 50 74 72 5b 69 5d 2e 70 50 67 3d 3d 30 20 29  aPtr[i].pPg==0 )
21aa0 3b 0a 20 20 20 20 20 20 20 20 20 20 70 50 74 72  ;.          pPtr
21ab0 20 3d 20 26 70 43 73 72 2d 3e 61 50 74 72 5b 69   = &pCsr->aPtr[i
21ac0 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ];.          rc 
21ad0 3d 20 73 65 67 6d 65 6e 74 50 74 72 4c 6f 61 64  = segmentPtrLoad
21ae0 50 61 67 65 28 70 44 62 2d 3e 70 46 53 2c 20 70  Page(pDb->pFS, p
21af0 50 74 72 2c 20 28 69 6e 74 29 70 49 6e 70 75 74  Ptr, (int)pInput
21b00 2d 3e 69 50 67 29 3b 0a 20 20 20 20 20 20 20 20  ->iPg);.        
21b10 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
21b20 20 26 26 20 70 50 74 72 2d 3e 6e 43 65 6c 6c 3e   && pPtr->nCell>
21b30 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  0 ){.           
21b40 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74 72   rc = segmentPtr
21b50 4c 6f 61 64 43 65 6c 6c 28 70 50 74 72 2c 20 70  LoadCell(pPtr, p
21b60 49 6e 70 75 74 2d 3e 69 43 65 6c 6c 29 3b 0a 20  Input->iCell);. 
21b70 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
21b80 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20     }.      }..  
21b90 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f      if( rc==LSM_
21ba0 4f 4b 20 26 26 20 70 43 73 72 2d 3e 70 42 74 43  OK && pCsr->pBtC
21bb0 73 72 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e  sr ){.        in
21bc0 74 20 28 2a 78 43 6d 70 29 28 76 6f 69 64 20 2a  t (*xCmp)(void *
21bd0 2c 20 69 6e 74 2c 20 76 6f 69 64 20 2a 2c 20 69  , int, void *, i
21be0 6e 74 29 20 3d 20 70 43 73 72 2d 3e 70 44 62 2d  nt) = pCsr->pDb-
21bf0 3e 78 43 6d 70 3b 0a 20 20 20 20 20 20 20 20 61  >xCmp;.        a
21c00 73 73 65 72 74 28 20 69 3d 3d 70 43 73 72 2d 3e  ssert( i==pCsr->
21c10 6e 50 74 72 20 29 3b 0a 20 20 20 20 20 20 20 20  nPtr );.        
21c20 72 63 20 3d 20 62 74 72 65 65 43 75 72 73 6f 72  rc = btreeCursor
21c30 52 65 73 74 6f 72 65 28 70 43 73 72 2d 3e 70 42  Restore(pCsr->pB
21c40 74 43 73 72 2c 20 78 43 6d 70 2c 20 26 70 4d 65  tCsr, xCmp, &pMe
21c50 72 67 65 2d 3e 61 49 6e 70 75 74 5b 69 5d 29 3b  rge->aInput[i]);
21c60 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
21c70 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
21c80 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 6d  {.        rc = m
21c90 75 6c 74 69 43 75 72 73 6f 72 53 65 74 75 70 54  ultiCursorSetupT
21ca0 72 65 65 28 70 43 73 72 2c 20 30 29 3b 0a 20 20  ree(pCsr, 0);.  
21cb0 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
21cc0 70 43 73 72 2d 3e 66 6c 61 67 73 20 7c 3d 20 43  pCsr->flags |= C
21cd0 55 52 53 4f 52 5f 4e 45 58 54 5f 4f 4b 3b 0a 20  URSOR_NEXT_OK;. 
21ce0 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
21cf0 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .}..static int s
21d00 6f 72 74 65 64 42 74 72 65 65 47 6f 62 62 6c 65  ortedBtreeGobble
21d10 28 0a 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62 2c  (.  lsm_db *pDb,
21d20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21d30 20 20 20 20 2f 2a 20 57 6f 72 6b 65 72 20 63 6f      /* Worker co
21d40 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 4d 75  nnection */.  Mu
21d50 6c 74 69 43 75 72 73 6f 72 20 2a 70 43 73 72 2c  ltiCursor *pCsr,
21d60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
21d70 20 4d 75 6c 74 69 2d 63 75 72 73 6f 72 20 62 65   Multi-cursor be
21d80 69 6e 67 20 75 73 65 64 20 66 6f 72 20 61 20 6d  ing used for a m
21d90 65 72 67 65 20 2a 2f 0a 20 20 69 6e 74 20 69 47  erge */.  int iG
21da0 6f 62 62 6c 65 20 20 20 20 20 20 20 20 20 20 20  obble           
21db0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70 43 73            /* pCs
21dc0 72 2d 3e 61 50 74 72 5b 5d 20 65 6e 74 72 79 20  r->aPtr[] entry 
21dd0 74 6f 20 6f 70 65 72 61 74 65 20 6f 6e 20 2a 2f  to operate on */
21de0 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c  .){.  int rc = L
21df0 53 4d 5f 4f 4b 3b 0a 20 20 69 66 28 20 72 74 54  SM_OK;.  if( rtT
21e00 6f 70 69 63 28 70 43 73 72 2d 3e 65 54 79 70 65  opic(pCsr->eType
21e10 29 3d 3d 30 20 29 7b 0a 20 20 20 20 53 65 67 6d  )==0 ){.    Segm
21e20 65 6e 74 20 2a 70 53 65 67 20 3d 20 70 43 73 72  ent *pSeg = pCsr
21e30 2d 3e 61 50 74 72 5b 69 47 6f 62 62 6c 65 5d 2e  ->aPtr[iGobble].
21e40 70 53 65 67 3b 0a 20 20 20 20 4c 73 6d 50 67 6e  pSeg;.    LsmPgn
21e50 6f 20 2a 61 50 67 3b 0a 20 20 20 20 69 6e 74 20  o *aPg;.    int 
21e60 6e 50 67 3b 0a 0a 20 20 20 20 2f 2a 20 53 65 65  nPg;..    /* See
21e70 6b 20 66 72 6f 6d 20 74 68 65 20 72 6f 6f 74 20  k from the root 
21e80 6f 66 20 74 68 65 20 62 2d 74 72 65 65 20 74 6f  of the b-tree to
21e90 20 74 68 65 20 73 65 67 6d 65 6e 74 20 6c 65 61   the segment lea
21ea0 66 20 74 68 61 74 20 6d 61 79 20 63 6f 6e 74 61  f that may conta
21eb0 69 6e 0a 20 20 20 20 2a 2a 20 61 20 6b 65 79 20  in.    ** a key 
21ec0 65 71 75 61 6c 20 74 6f 20 74 68 65 20 6f 6e 65  equal to the one
21ed0 20 6d 75 6c 74 69 2d 63 75 72 73 6f 72 20 63 75   multi-cursor cu
21ee0 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74  rrently points t
21ef0 6f 2e 20 52 65 63 6f 72 64 20 74 68 65 0a 20 20  o. Record the.  
21f00 20 20 2a 2a 20 70 61 67 65 20 6e 75 6d 62 65 72    ** page number
21f10 20 6f 66 20 65 61 63 68 20 62 2d 74 72 65 65 20   of each b-tree 
21f20 70 61 67 65 20 61 6e 64 20 74 68 65 20 6c 65 61  page and the lea
21f30 66 2e 20 54 68 65 20 73 65 67 6d 65 6e 74 20 6d  f. The segment m
21f40 61 79 20 62 65 0a 20 20 20 20 2a 2a 20 67 6f 62  ay be.    ** gob
21f50 62 6c 65 64 20 75 70 20 74 6f 20 28 62 75 74 20  bled up to (but 
21f60 6e 6f 74 20 69 6e 63 6c 75 64 69 6e 67 29 20 74  not including) t
21f70 68 65 20 66 69 72 73 74 20 6f 66 20 74 68 65 73  he first of thes
21f80 65 20 70 61 67 65 20 6e 75 6d 62 65 72 73 2e 0a  e page numbers..
21f90 20 20 20 20 2a 2f 0a 20 20 20 20 61 73 73 65 72      */.    asser
21fa0 74 28 20 70 53 65 67 2d 3e 69 52 6f 6f 74 3e 30  t( pSeg->iRoot>0
21fb0 20 29 3b 0a 20 20 20 20 61 50 67 20 3d 20 6c 73   );.    aPg = ls
21fc0 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28 70 44  mMallocZeroRc(pD
21fd0 62 2d 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66 28  b->pEnv, sizeof(
21fe0 4c 73 6d 50 67 6e 6f 29 2a 33 32 2c 20 26 72 63  LsmPgno)*32, &rc
21ff0 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  );.    if( rc==L
22000 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  SM_OK ){.      r
22010 63 20 3d 20 73 65 65 6b 49 6e 42 74 72 65 65 28  c = seekInBtree(
22020 70 43 73 72 2c 20 70 53 65 67 2c 20 0a 20 20 20  pCsr, pSeg, .   
22030 20 20 20 20 20 20 20 72 74 54 6f 70 69 63 28 70         rtTopic(p
22040 43 73 72 2d 3e 65 54 79 70 65 29 2c 20 70 43 73  Csr->eType), pCs
22050 72 2d 3e 6b 65 79 2e 70 44 61 74 61 2c 20 70 43  r->key.pData, pC
22060 73 72 2d 3e 6b 65 79 2e 6e 44 61 74 61 2c 20 61  sr->key.nData, a
22070 50 67 2c 20 30 0a 20 20 20 20 20 20 29 3b 20 0a  Pg, 0.      ); .
22080 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72      }..    if( r
22090 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
220a0 20 20 20 66 6f 72 28 6e 50 67 3d 30 3b 20 61 50     for(nPg=0; aP
220b0 67 5b 6e 50 67 5d 3b 20 6e 50 67 2b 2b 29 3b 0a  g[nPg]; nPg++);.
220c0 20 20 20 20 20 20 6c 73 6d 46 73 47 6f 62 62 6c        lsmFsGobbl
220d0 65 28 70 44 62 2c 20 70 53 65 67 2c 20 61 50 67  e(pDb, pSeg, aPg
220e0 2c 20 6e 50 67 29 3b 0a 20 20 20 20 7d 0a 0a 20  , nPg);.    }.. 
220f0 20 20 20 6c 73 6d 46 72 65 65 28 70 44 62 2d 3e     lsmFree(pDb->
22100 70 45 6e 76 2c 20 61 50 67 29 3b 0a 20 20 7d 0a  pEnv, aPg);.  }.
22110 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
22120 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 70  /*.** Argument p
22130 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 6c 65 76   points to a lev
22140 65 6c 20 6f 66 20 61 67 65 20 4e 2e 20 52 65 74  el of age N. Ret
22150 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  urn the number o
22160 66 20 6c 65 76 65 6c 73 20 69 6e 0a 2a 2a 20 74  f levels in.** t
22170 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 73  he linked list s
22180 74 61 72 74 69 6e 67 20 61 74 20 70 20 74 68 61  tarting at p tha
22190 74 20 68 61 76 65 20 61 67 65 3d 4e 20 28 61 6c  t have age=N (al
221a0 77 61 79 73 20 61 74 20 6c 65 61 73 74 20 31 29  ways at least 1)
221b0 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
221c0 73 6f 72 74 65 64 43 6f 75 6e 74 4c 65 76 65 6c  sortedCountLevel
221d0 73 28 4c 65 76 65 6c 20 2a 70 29 7b 0a 20 20 69  s(Level *p){.  i
221e0 6e 74 20 69 41 67 65 20 3d 20 70 2d 3e 69 41 67  nt iAge = p->iAg
221f0 65 3b 0a 20 20 69 6e 74 20 6e 52 65 74 20 3d 20  e;.  int nRet = 
22200 30 3b 0a 20 20 64 6f 20 7b 0a 20 20 20 20 6e 52  0;.  do {.    nR
22210 65 74 2b 2b 3b 0a 20 20 20 20 70 20 3d 20 70 2d  et++;.    p = p-
22220 3e 70 4e 65 78 74 3b 0a 20 20 7d 77 68 69 6c 65  >pNext;.  }while
22230 28 20 70 20 26 26 20 70 2d 3e 69 41 67 65 3d 3d  ( p && p->iAge==
22240 69 41 67 65 20 29 3b 0a 20 20 72 65 74 75 72 6e  iAge );.  return
22250 20 6e 52 65 74 3b 0a 7d 0a 0a 73 74 61 74 69 63   nRet;.}..static
22260 20 69 6e 74 20 73 6f 72 74 65 64 53 65 6c 65 63   int sortedSelec
22270 74 4c 65 76 65 6c 28 6c 73 6d 5f 64 62 20 2a 70  tLevel(lsm_db *p
22280 44 62 2c 20 69 6e 74 20 6e 4d 65 72 67 65 2c 20  Db, int nMerge, 
22290 4c 65 76 65 6c 20 2a 2a 70 70 4f 75 74 29 7b 0a  Level **ppOut){.
222a0 20 20 4c 65 76 65 6c 20 2a 70 54 6f 70 4c 65 76    Level *pTopLev
222b0 65 6c 20 3d 20 6c 73 6d 44 62 53 6e 61 70 73 68  el = lsmDbSnapsh
222c0 6f 74 4c 65 76 65 6c 28 70 44 62 2d 3e 70 57 6f  otLevel(pDb->pWo
222d0 72 6b 65 72 29 3b 0a 20 20 69 6e 74 20 72 63 20  rker);.  int rc 
222e0 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 4c 65 76 65  = LSM_OK;.  Leve
222f0 6c 20 2a 70 4c 65 76 65 6c 20 3d 20 30 3b 20 20  l *pLevel = 0;  
22300 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 75 74            /* Out
22310 70 75 74 20 76 61 6c 75 65 20 2a 2f 0a 20 20 4c  put value */.  L
22320 65 76 65 6c 20 2a 70 42 65 73 74 20 3d 20 30 3b  evel *pBest = 0;
22330 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
22340 42 65 73 74 20 6c 65 76 65 6c 20 74 6f 20 77 6f  Best level to wo
22350 72 6b 20 6f 6e 20 66 6f 75 6e 64 20 73 6f 20 66  rk on found so f
22360 61 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 65 73  ar */.  int nBes
22370 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
22380 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
22390 6f 66 20 73 65 67 6d 65 6e 74 73 20 6d 65 72 67  of segments merg
223a0 65 64 20 61 74 20 70 42 65 73 74 20 2a 2f 0a 20  ed at pBest */. 
223b0 20 4c 65 76 65 6c 20 2a 70 54 68 69 73 20 3d 20   Level *pThis = 
223c0 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  0;             /
223d0 2a 20 46 69 72 73 74 20 69 6e 20 72 75 6e 20 6f  * First in run o
223e0 66 20 6c 65 76 65 6c 73 20 77 69 74 68 20 61 67  f levels with ag
223f0 65 3d 69 41 67 65 20 2a 2f 0a 20 20 69 6e 74 20  e=iAge */.  int 
22400 6e 54 68 69 73 20 3d 20 30 3b 20 20 20 20 20 20  nThis = 0;      
22410 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
22420 62 65 72 20 6f 66 20 6c 65 76 65 6c 73 20 73 74  ber of levels st
22430 61 72 74 69 6e 67 20 61 74 20 70 54 68 69 73 20  arting at pThis 
22440 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 4d  */..  assert( nM
22450 65 72 67 65 3e 3d 31 20 29 3b 0a 20 20 6e 42 65  erge>=1 );.  nBe
22460 73 74 20 3d 20 4c 53 4d 5f 4d 41 58 28 31 2c 20  st = LSM_MAX(1, 
22470 6e 4d 65 72 67 65 2d 31 29 3b 0a 0a 20 20 2f 2a  nMerge-1);..  /*
22480 20 46 69 6e 64 20 74 68 65 20 6c 6f 6e 67 65 73   Find the longes
22490 74 20 63 6f 6e 74 69 67 75 6f 75 73 20 72 75 6e  t contiguous run
224a0 20 6f 66 20 6c 65 76 65 6c 73 20 6e 6f 74 20 63   of levels not c
224b0 75 72 72 65 6e 74 6c 79 20 75 6e 64 65 72 67 6f  urrently undergo
224c0 69 6e 67 20 61 20 0a 20 20 2a 2a 20 6d 65 72 67  ing a .  ** merg
224d0 65 20 77 69 74 68 20 74 68 65 20 73 61 6d 65 20  e with the same 
224e0 61 67 65 20 69 6e 20 74 68 65 20 73 74 72 75 63  age in the struc
224f0 74 75 72 65 2e 20 4f 72 20 74 68 65 20 6c 65 76  ture. Or the lev
22500 65 6c 20 62 65 69 6e 67 20 6d 65 72 67 65 64 0a  el being merged.
22510 20 20 2a 2a 20 77 69 74 68 20 74 68 65 20 6c 61    ** with the la
22520 72 67 65 73 74 20 6e 75 6d 62 65 72 20 6f 66 20  rgest number of 
22530 72 69 67 68 74 2d 68 61 6e 64 20 73 65 67 6d 65  right-hand segme
22540 6e 74 73 2e 20 57 6f 72 6b 20 6f 6e 20 69 74 2e  nts. Work on it.
22550 20 2a 2f 0a 20 20 66 6f 72 28 70 4c 65 76 65 6c   */.  for(pLevel
22560 3d 70 54 6f 70 4c 65 76 65 6c 3b 20 70 4c 65 76  =pTopLevel; pLev
22570 65 6c 3b 20 70 4c 65 76 65 6c 3d 70 4c 65 76 65  el; pLevel=pLeve
22580 6c 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 69  l->pNext){.    i
22590 66 28 20 70 4c 65 76 65 6c 2d 3e 6e 52 69 67 68  f( pLevel->nRigh
225a0 74 3d 3d 30 20 26 26 20 70 54 68 69 73 20 26 26  t==0 && pThis &&
225b0 20 70 4c 65 76 65 6c 2d 3e 69 41 67 65 3d 3d 70   pLevel->iAge==p
225c0 54 68 69 73 2d 3e 69 41 67 65 20 29 7b 0a 20 20  This->iAge ){.  
225d0 20 20 20 20 6e 54 68 69 73 2b 2b 3b 0a 20 20 20      nThis++;.   
225e0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66   }else{.      if
225f0 28 20 6e 54 68 69 73 3e 6e 42 65 73 74 20 29 7b  ( nThis>nBest ){
22600 0a 20 20 20 20 20 20 20 20 69 66 28 20 28 70 4c  .        if( (pL
22610 65 76 65 6c 2d 3e 69 41 67 65 21 3d 70 54 68 69  evel->iAge!=pThi
22620 73 2d 3e 69 41 67 65 2b 31 29 0a 20 20 20 20 20  s->iAge+1).     
22630 20 20 20 20 7c 7c 20 28 70 4c 65 76 65 6c 2d 3e      || (pLevel->
22640 6e 52 69 67 68 74 3d 3d 30 20 26 26 20 73 6f 72  nRight==0 && sor
22650 74 65 64 43 6f 75 6e 74 4c 65 76 65 6c 73 28 70  tedCountLevels(p
22660 4c 65 76 65 6c 29 3c 3d 70 44 62 2d 3e 6e 4d 65  Level)<=pDb->nMe
22670 72 67 65 29 0a 20 20 20 20 20 20 20 20 29 7b 0a  rge).        ){.
22680 20 20 20 20 20 20 20 20 20 20 70 42 65 73 74 20            pBest 
22690 3d 20 70 54 68 69 73 3b 0a 20 20 20 20 20 20 20  = pThis;.       
226a0 20 20 20 6e 42 65 73 74 20 3d 20 6e 54 68 69 73     nBest = nThis
226b0 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
226c0 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 70 4c    }.      if( pL
226d0 65 76 65 6c 2d 3e 6e 52 69 67 68 74 20 29 7b 0a  evel->nRight ){.
226e0 20 20 20 20 20 20 20 20 69 66 28 20 70 4c 65 76          if( pLev
226f0 65 6c 2d 3e 6e 52 69 67 68 74 3e 6e 42 65 73 74  el->nRight>nBest
22700 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6e 42   ){.          nB
22710 65 73 74 20 3d 20 70 4c 65 76 65 6c 2d 3e 6e 52  est = pLevel->nR
22720 69 67 68 74 3b 0a 20 20 20 20 20 20 20 20 20 20  ight;.          
22730 70 42 65 73 74 20 3d 20 70 4c 65 76 65 6c 3b 0a  pBest = pLevel;.
22740 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
22750 20 20 6e 54 68 69 73 20 3d 20 30 3b 0a 20 20 20    nThis = 0;.   
22760 20 20 20 20 20 70 54 68 69 73 20 3d 20 30 3b 0a       pThis = 0;.
22770 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
22780 20 20 20 20 20 70 54 68 69 73 20 3d 20 70 4c 65       pThis = pLe
22790 76 65 6c 3b 0a 20 20 20 20 20 20 20 20 6e 54 68  vel;.        nTh
227a0 69 73 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a  is = 1;.      }.
227b0 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20      }.  }.  if( 
227c0 6e 54 68 69 73 3e 6e 42 65 73 74 20 29 7b 0a 20  nThis>nBest ){. 
227d0 20 20 20 61 73 73 65 72 74 28 20 70 54 68 69 73     assert( pThis
227e0 20 29 3b 0a 20 20 20 20 70 42 65 73 74 20 3d 20   );.    pBest = 
227f0 70 54 68 69 73 3b 0a 20 20 20 20 6e 42 65 73 74  pThis;.    nBest
22800 20 3d 20 6e 54 68 69 73 3b 0a 20 20 7d 0a 0a 20   = nThis;.  }.. 
22810 20 69 66 28 20 70 42 65 73 74 3d 3d 30 20 26 26   if( pBest==0 &&
22820 20 6e 4d 65 72 67 65 3d 3d 31 20 29 7b 0a 20 20   nMerge==1 ){.  
22830 20 20 69 6e 74 20 6e 46 72 65 65 20 3d 20 30 3b    int nFree = 0;
22840 0a 20 20 20 20 69 6e 74 20 6e 55 73 72 20 3d 20  .    int nUsr = 
22850 30 3b 0a 20 20 20 20 66 6f 72 28 70 4c 65 76 65  0;.    for(pLeve
22860 6c 3d 70 54 6f 70 4c 65 76 65 6c 3b 20 70 4c 65  l=pTopLevel; pLe
22870 76 65 6c 3b 20 70 4c 65 76 65 6c 3d 70 4c 65 76  vel; pLevel=pLev
22880 65 6c 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  el->pNext){.    
22890 20 20 61 73 73 65 72 74 28 20 21 70 4c 65 76 65    assert( !pLeve
228a0 6c 2d 3e 6e 52 69 67 68 74 20 29 3b 0a 20 20 20  l->nRight );.   
228b0 20 20 20 69 66 28 20 70 4c 65 76 65 6c 2d 3e 66     if( pLevel->f
228c0 6c 61 67 73 20 26 20 4c 45 56 45 4c 5f 46 52 45  lags & LEVEL_FRE
228d0 45 4c 49 53 54 5f 4f 4e 4c 59 20 29 7b 0a 20 20  ELIST_ONLY ){.  
228e0 20 20 20 20 20 20 6e 46 72 65 65 2b 2b 3b 0a 20        nFree++;. 
228f0 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
22900 20 20 20 20 6e 55 73 72 2b 2b 3b 0a 20 20 20 20      nUsr++;.    
22910 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
22920 28 20 6e 55 73 72 3e 31 20 29 7b 0a 20 20 20 20  ( nUsr>1 ){.    
22930 20 20 70 42 65 73 74 20 3d 20 70 54 6f 70 4c 65    pBest = pTopLe
22940 76 65 6c 3b 0a 20 20 20 20 20 20 6e 42 65 73 74  vel;.      nBest
22950 20 3d 20 6e 46 72 65 65 20 2b 20 6e 55 73 72 3b   = nFree + nUsr;
22960 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
22970 28 20 70 42 65 73 74 20 29 7b 0a 20 20 20 20 69  ( pBest ){.    i
22980 66 28 20 70 42 65 73 74 2d 3e 6e 52 69 67 68 74  f( pBest->nRight
22990 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20  ==0 ){.      rc 
229a0 3d 20 73 6f 72 74 65 64 4d 65 72 67 65 53 65 74  = sortedMergeSet
229b0 75 70 28 70 44 62 2c 20 70 42 65 73 74 2c 20 6e  up(pDb, pBest, n
229c0 42 65 73 74 2c 20 70 70 4f 75 74 29 3b 0a 20 20  Best, ppOut);.  
229d0 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a    }else{.      *
229e0 70 70 4f 75 74 20 3d 20 70 42 65 73 74 3b 0a 20  ppOut = pBest;. 
229f0 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
22a00 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
22a10 20 69 6e 74 20 73 6f 72 74 65 64 44 62 49 73 46   int sortedDbIsF
22a20 75 6c 6c 28 6c 73 6d 5f 64 62 20 2a 70 44 62 29  ull(lsm_db *pDb)
22a30 7b 0a 20 20 4c 65 76 65 6c 20 2a 70 54 6f 70 20  {.  Level *pTop 
22a40 3d 20 6c 73 6d 44 62 53 6e 61 70 73 68 6f 74 4c  = lsmDbSnapshotL
22a50 65 76 65 6c 28 70 44 62 2d 3e 70 57 6f 72 6b 65  evel(pDb->pWorke
22a60 72 29 3b 0a 0a 20 20 69 66 28 20 6c 73 6d 44 61  r);..  if( lsmDa
22a70 74 61 62 61 73 65 46 75 6c 6c 28 70 44 62 29 20  tabaseFull(pDb) 
22a80 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 69 66  ) return 1;.  if
22a90 28 20 70 54 6f 70 20 26 26 20 70 54 6f 70 2d 3e  ( pTop && pTop->
22aa0 69 41 67 65 3d 3d 30 0a 20 20 20 26 26 20 28 70  iAge==0.   && (p
22ab0 54 6f 70 2d 3e 6e 52 69 67 68 74 20 7c 7c 20 73  Top->nRight || s
22ac0 6f 72 74 65 64 43 6f 75 6e 74 4c 65 76 65 6c 73  ortedCountLevels
22ad0 28 70 54 6f 70 29 3e 3d 70 44 62 2d 3e 6e 4d 65  (pTop)>=pDb->nMe
22ae0 72 67 65 29 0a 20 20 29 7b 0a 20 20 20 20 72 65  rge).  ){.    re
22af0 74 75 72 6e 20 31 3b 0a 20 20 7d 0a 20 20 72 65  turn 1;.  }.  re
22b00 74 75 72 6e 20 30 3b 0a 7d 0a 0a 74 79 70 65 64  turn 0;.}..typed
22b10 65 66 20 73 74 72 75 63 74 20 4d 6f 76 65 42 6c  ef struct MoveBl
22b20 6f 63 6b 43 74 78 20 4d 6f 76 65 42 6c 6f 63 6b  ockCtx MoveBlock
22b30 43 74 78 3b 0a 73 74 72 75 63 74 20 4d 6f 76 65  Ctx;.struct Move
22b40 42 6c 6f 63 6b 43 74 78 20 7b 0a 20 20 69 6e 74  BlockCtx {.  int
22b50 20 69 53 65 65 6e 3b 20 20 20 20 20 20 20 20 20   iSeen;         
22b60 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
22b70 50 72 65 76 69 6f 75 73 20 66 72 65 65 20 62 6c  Previous free bl
22b80 6f 63 6b 20 6f 6e 20 6c 69 73 74 20 2a 2f 0a 20  ock on list */. 
22b90 20 69 6e 74 20 69 46 72 6f 6d 3b 20 20 20 20 20   int iFrom;     
22ba0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22bb0 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72   /* Total number
22bc0 20 6f 66 20 62 6c 6f 63 6b 73 20 69 6e 20 66 69   of blocks in fi
22bd0 6c 65 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74 69 63  le */.};..static
22be0 20 69 6e 74 20 6d 6f 76 65 42 6c 6f 63 6b 43 62   int moveBlockCb
22bf0 28 76 6f 69 64 20 2a 70 43 74 78 2c 20 69 6e 74  (void *pCtx, int
22c00 20 69 42 6c 6b 2c 20 69 36 34 20 69 53 6e 61 70   iBlk, i64 iSnap
22c10 73 68 6f 74 29 7b 0a 20 20 4d 6f 76 65 42 6c 6f  shot){.  MoveBlo
22c20 63 6b 43 74 78 20 2a 70 20 3d 20 28 4d 6f 76 65  ckCtx *p = (Move
22c30 42 6c 6f 63 6b 43 74 78 20 2a 29 70 43 74 78 3b  BlockCtx *)pCtx;
22c40 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 69 46  .  assert( p->iF
22c50 72 6f 6d 3d 3d 30 20 29 3b 0a 20 20 69 66 28 20  rom==0 );.  if( 
22c60 69 42 6c 6b 3d 3d 28 70 2d 3e 69 53 65 65 6e 2d  iBlk==(p->iSeen-
22c70 31 29 20 29 7b 0a 20 20 20 20 70 2d 3e 69 53 65  1) ){.    p->iSe
22c80 65 6e 20 3d 20 69 42 6c 6b 3b 0a 20 20 20 20 72  en = iBlk;.    r
22c90 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 70  eturn 0;.  }.  p
22ca0 2d 3e 69 46 72 6f 6d 20 3d 20 70 2d 3e 69 53 65  ->iFrom = p->iSe
22cb0 65 6e 2d 31 3b 0a 20 20 72 65 74 75 72 6e 20 31  en-1;.  return 1
22cc0 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
22cd0 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
22ce0 65 64 20 74 6f 20 66 75 72 74 68 65 72 20 63 6f  ed to further co
22cf0 6d 70 61 63 74 20 61 20 64 61 74 61 62 61 73 65  mpact a database
22d00 20 66 6f 72 20 77 68 69 63 68 20 61 6c 6c 20 0a   for which all .
22d10 2a 2a 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e  ** of the conten
22d20 74 20 68 61 73 20 61 6c 72 65 61 64 79 20 62 65  t has already be
22d30 65 6e 20 6d 65 72 67 65 64 20 69 6e 74 6f 20 61  en merged into a
22d40 20 73 69 6e 67 6c 65 20 73 65 67 6d 65 6e 74 2e   single segment.
22d50 20 49 66 20 0a 2a 2a 20 70 6f 73 73 69 62 6c 65   If .** possible
22d60 2c 20 69 74 20 6d 6f 76 65 73 20 74 68 65 20 63  , it moves the c
22d70 6f 6e 74 65 6e 74 73 20 6f 66 20 61 20 73 69 6e  ontents of a sin
22d80 67 6c 65 20 62 6c 6f 63 6b 20 66 72 6f 6d 20 74  gle block from t
22d90 68 65 20 65 6e 64 20 6f 66 20 74 68 65 0a 2a 2a  he end of the.**
22da0 20 66 69 6c 65 20 74 6f 20 61 20 66 72 65 65 2d   file to a free-
22db0 62 6c 6f 63 6b 20 74 68 61 74 20 6c 69 65 73 20  block that lies 
22dc0 63 6c 6f 73 65 72 20 74 6f 20 74 68 65 20 73 74  closer to the st
22dd0 61 72 74 20 6f 66 20 74 68 65 20 66 69 6c 65 20  art of the file 
22de0 28 61 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 74 68 65  (allowing.** the
22df0 20 66 69 6c 65 20 74 6f 20 62 65 20 65 76 65 6e   file to be even
22e00 74 75 61 6c 6c 79 20 74 72 75 6e 63 61 74 65 64  tually truncated
22e10 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  )..*/.static int
22e20 20 73 6f 72 74 65 64 4d 6f 76 65 42 6c 6f 63 6b   sortedMoveBlock
22e30 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 69 6e  (lsm_db *pDb, in
22e40 74 20 2a 70 6e 57 72 69 74 65 29 7b 0a 20 20 53  t *pnWrite){.  S
22e50 6e 61 70 73 68 6f 74 20 2a 70 20 3d 20 70 44 62  napshot *p = pDb
22e60 2d 3e 70 57 6f 72 6b 65 72 3b 0a 20 20 4c 65 76  ->pWorker;.  Lev
22e70 65 6c 20 2a 70 4c 76 6c 20 3d 20 6c 73 6d 44 62  el *pLvl = lsmDb
22e80 53 6e 61 70 73 68 6f 74 4c 65 76 65 6c 28 70 29  SnapshotLevel(p)
22e90 3b 0a 20 20 69 6e 74 20 69 46 72 6f 6d 3b 20 20  ;.  int iFrom;  
22ea0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22eb0 20 20 20 20 2f 2a 20 42 6c 6f 63 6b 20 74 6f 20      /* Block to 
22ec0 6d 6f 76 65 20 2a 2f 0a 20 20 69 6e 74 20 69 54  move */.  int iT
22ed0 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o;              
22ee0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73            /* Des
22ef0 74 69 6e 61 74 69 6f 6e 20 74 6f 20 6d 6f 76 65  tination to move
22f00 20 62 6c 6f 63 6b 20 74 6f 20 2a 2f 0a 20 20 69   block to */.  i
22f10 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
22f20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
22f30 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
22f40 0a 0a 20 20 4d 6f 76 65 42 6c 6f 63 6b 43 74 78  ..  MoveBlockCtx
22f50 20 73 43 74 78 3b 0a 0a 20 20 61 73 73 65 72 74   sCtx;..  assert
22f60 28 20 70 4c 76 6c 2d 3e 70 4e 65 78 74 3d 3d 30  ( pLvl->pNext==0
22f70 20 26 26 20 70 4c 76 6c 2d 3e 6e 52 69 67 68 74   && pLvl->nRight
22f80 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
22f90 20 70 2d 3e 72 65 64 69 72 65 63 74 2e 6e 3c 3d   p->redirect.n<=
22fa0 4c 53 4d 5f 4d 41 58 5f 42 4c 4f 43 4b 5f 52 45  LSM_MAX_BLOCK_RE
22fb0 44 49 52 45 43 54 53 20 29 3b 0a 0a 20 20 2a 70  DIRECTS );..  *p
22fc0 6e 57 72 69 74 65 20 3d 20 30 3b 0a 0a 20 20 2f  nWrite = 0;..  /
22fd0 2a 20 43 68 65 63 6b 20 74 68 61 74 20 74 68 65  * Check that the
22fe0 20 72 65 64 69 72 65 63 74 20 61 72 72 61 79 20   redirect array 
22ff0 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 66  is not already f
23000 75 6c 6c 2e 20 49 66 20 69 74 20 69 73 2c 20 72  ull. If it is, r
23010 65 74 75 72 6e 0a 20 20 2a 2a 20 77 69 74 68 6f  eturn.  ** witho
23020 75 74 20 6d 6f 76 69 6e 67 20 61 6e 79 20 64 61  ut moving any da
23030 74 61 62 61 73 65 20 63 6f 6e 74 65 6e 74 2e 20  tabase content. 
23040 20 2a 2f 0a 20 20 69 66 28 20 70 2d 3e 72 65 64   */.  if( p->red
23050 69 72 65 63 74 2e 6e 3e 3d 4c 53 4d 5f 4d 41 58  irect.n>=LSM_MAX
23060 5f 42 4c 4f 43 4b 5f 52 45 44 49 52 45 43 54 53  _BLOCK_REDIRECTS
23070 20 29 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b   ) return LSM_OK
23080 3b 0a 0a 20 20 2f 2a 20 46 69 6e 64 20 74 68 65  ;..  /* Find the
23090 20 6c 61 73 74 20 62 6c 6f 63 6b 20 6f 66 20 63   last block of c
230a0 6f 6e 74 65 6e 74 20 69 6e 20 74 68 65 20 64 61  ontent in the da
230b0 74 61 62 61 73 65 20 66 69 6c 65 2e 20 44 6f 20  tabase file. Do 
230c0 74 68 69 73 20 62 79 20 0a 20 20 2a 2a 20 74 72  this by .  ** tr
230d0 61 76 65 72 73 69 6e 67 20 74 68 65 20 66 72 65  aversing the fre
230e0 65 2d 6c 69 73 74 20 69 6e 20 72 65 76 65 72 73  e-list in revers
230f0 65 20 28 64 65 73 63 65 6e 64 69 6e 67 20 62 6c  e (descending bl
23100 6f 63 6b 20 6e 75 6d 62 65 72 29 20 6f 72 64 65  ock number) orde
23110 72 2e 0a 20 20 2a 2a 20 54 68 65 20 66 69 72 73  r..  ** The firs
23120 74 20 62 6c 6f 63 6b 20 6e 6f 74 20 6f 6e 20 74  t block not on t
23130 68 65 20 66 72 65 65 20 6c 69 73 74 20 69 73 20  he free list is 
23140 74 68 65 20 6f 6e 65 20 74 68 61 74 20 77 69 6c  the one that wil
23150 6c 20 62 65 20 6d 6f 76 65 64 2e 0a 20 20 2a 2a  l be moved..  **
23160 20 53 69 6e 63 65 20 74 68 65 20 64 62 20 63 6f   Since the db co
23170 6e 73 69 73 74 73 20 6f 66 20 61 20 73 69 6e 67  nsists of a sing
23180 6c 65 20 73 65 67 6d 65 6e 74 2c 20 74 68 65 72  le segment, ther
23190 65 20 69 73 20 6e 6f 20 61 6d 62 69 67 75 69 74  e is no ambiguit
231a0 79 20 61 73 0a 20 20 2a 2a 20 74 6f 20 77 68 69  y as.  ** to whi
231b0 63 68 20 73 65 67 6d 65 6e 74 20 74 68 65 20 62  ch segment the b
231c0 6c 6f 63 6b 20 62 65 6c 6f 6e 67 73 20 74 6f 2e  lock belongs to.
231d0 20 20 2a 2f 0a 20 20 73 43 74 78 2e 69 53 65 65    */.  sCtx.iSee
231e0 6e 20 3d 20 70 2d 3e 6e 42 6c 6f 63 6b 2b 31 3b  n = p->nBlock+1;
231f0 0a 20 20 73 43 74 78 2e 69 46 72 6f 6d 20 3d 20  .  sCtx.iFrom = 
23200 30 3b 0a 20 20 72 63 20 3d 20 6c 73 6d 57 61 6c  0;.  rc = lsmWal
23210 6b 46 72 65 65 6c 69 73 74 28 70 44 62 2c 20 31  kFreelist(pDb, 1
23220 2c 20 6d 6f 76 65 42 6c 6f 63 6b 43 62 2c 20 26  , moveBlockCb, &
23230 73 43 74 78 29 3b 0a 20 20 69 66 28 20 72 63 21  sCtx);.  if( rc!
23240 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 73 43 74 78 2e  =LSM_OK || sCtx.
23250 69 46 72 6f 6d 3d 3d 30 20 29 20 72 65 74 75 72  iFrom==0 ) retur
23260 6e 20 72 63 3b 0a 20 20 69 46 72 6f 6d 20 3d 20  n rc;.  iFrom = 
23270 73 43 74 78 2e 69 46 72 6f 6d 3b 0a 0a 20 20 2f  sCtx.iFrom;..  /
23280 2a 20 46 69 6e 64 20 74 68 65 20 66 69 72 73 74  * Find the first
23290 20 66 72 65 65 20 62 6c 6f 63 6b 20 69 6e 20 74   free block in t
232a0 68 65 20 64 61 74 61 62 61 73 65 2c 20 69 67 6e  he database, ign
232b0 6f 72 69 6e 67 20 62 6c 6f 63 6b 20 31 2e 20 42  oring block 1. B
232c0 6c 6f 63 6b 0a 20 20 2a 2a 20 31 20 69 73 20 74  lock.  ** 1 is t
232d0 72 69 63 6b 79 20 61 73 20 69 74 20 69 73 20 73  ricky as it is s
232e0 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74 68 65 20  maller than the 
232f0 6f 74 68 65 72 20 62 6c 6f 63 6b 73 2e 20 20 2a  other blocks.  *
23300 2f 0a 20 20 72 63 20 3d 20 6c 73 6d 42 6c 6f 63  /.  rc = lsmBloc
23310 6b 41 6c 6c 6f 63 61 74 65 28 70 44 62 2c 20 69  kAllocate(pDb, i
23320 46 72 6f 6d 2c 20 26 69 54 6f 29 3b 0a 20 20 69  From, &iTo);.  i
23330 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c 7c  f( rc!=LSM_OK ||
23340 20 69 54 6f 3d 3d 30 20 29 20 72 65 74 75 72 6e   iTo==0 ) return
23350 20 72 63 3b 0a 20 20 61 73 73 65 72 74 28 20 69   rc;.  assert( i
23360 54 6f 21 3d 31 20 26 26 20 69 54 6f 3c 69 46 72  To!=1 && iTo<iFr
23370 6f 6d 20 29 3b 0a 0a 20 20 72 63 20 3d 20 6c 73  om );..  rc = ls
23380 6d 46 73 4d 6f 76 65 42 6c 6f 63 6b 28 70 44 62  mFsMoveBlock(pDb
23390 2d 3e 70 46 53 2c 20 26 70 4c 76 6c 2d 3e 6c 68  ->pFS, &pLvl->lh
233a0 73 2c 20 69 54 6f 2c 20 69 46 72 6f 6d 29 3b 0a  s, iTo, iFrom);.
233b0 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
233c0 20 29 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e 72   ){.    if( p->r
233d0 65 64 69 72 65 63 74 2e 61 3d 3d 30 20 29 7b 0a  edirect.a==0 ){.
233e0 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20        int nByte 
233f0 3d 20 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20  = sizeof(struct 
23400 52 65 64 69 72 65 63 74 45 6e 74 72 79 29 20 2a  RedirectEntry) *
23410 20 4c 53 4d 5f 4d 41 58 5f 42 4c 4f 43 4b 5f 52   LSM_MAX_BLOCK_R
23420 45 44 49 52 45 43 54 53 3b 0a 20 20 20 20 20 20  EDIRECTS;.      
23430 70 2d 3e 72 65 64 69 72 65 63 74 2e 61 20 3d 20  p->redirect.a = 
23440 6c 73 6d 4d 61 6c 6c 6f 63 5a 65 72 6f 52 63 28  lsmMallocZeroRc(
23450 70 44 62 2d 3e 70 45 6e 76 2c 20 6e 42 79 74 65  pDb->pEnv, nByte
23460 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d 0a 20 20  , &rc);.    }.  
23470 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
23480 20 29 7b 0a 0a 20 20 20 20 20 20 2f 2a 20 43 68   ){..      /* Ch
23490 65 63 6b 20 69 66 20 74 68 65 20 62 6c 6f 63 6b  eck if the block
234a0 20 6a 75 73 74 20 6d 6f 76 65 64 20 77 61 73 20   just moved was 
234b0 61 6c 72 65 61 64 79 20 72 65 64 69 72 65 63 74  already redirect
234c0 65 64 2e 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  ed. */.      int
234d0 20 69 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d   i;.      for(i=
234e0 30 3b 20 69 3c 70 2d 3e 72 65 64 69 72 65 63 74  0; i<p->redirect
234f0 2e 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  .n; i++){.      
23500 20 20 69 66 28 20 70 2d 3e 72 65 64 69 72 65 63    if( p->redirec
23510 74 2e 61 5b 69 5d 2e 69 54 6f 3d 3d 69 46 72 6f  t.a[i].iTo==iFro
23520 6d 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  m ) break;.     
23530 20 7d 0a 0a 20 20 20 20 20 20 69 66 28 20 69 3d   }..      if( i=
23540 3d 70 2d 3e 72 65 64 69 72 65 63 74 2e 6e 20 29  =p->redirect.n )
23550 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 42 6c 6f  {.        /* Blo
23560 63 6b 20 69 46 72 6f 6d 20 77 61 73 20 6e 6f 74  ck iFrom was not
23570 20 61 6c 72 65 61 64 79 20 72 65 64 69 72 65 63   already redirec
23580 74 65 64 2e 20 41 64 64 20 61 20 6e 65 77 20 61  ted. Add a new a
23590 72 72 61 79 20 65 6e 74 72 79 2e 20 2a 2f 0a 20  rray entry. */. 
235a0 20 20 20 20 20 20 20 6d 65 6d 6d 6f 76 65 28 26         memmove(&
235b0 70 2d 3e 72 65 64 69 72 65 63 74 2e 61 5b 31 5d  p->redirect.a[1]
235c0 2c 20 26 70 2d 3e 72 65 64 69 72 65 63 74 2e 61  , &p->redirect.a
235d0 5b 30 5d 2c 20 0a 20 20 20 20 20 20 20 20 20 20  [0], .          
235e0 20 20 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20    sizeof(struct 
235f0 52 65 64 69 72 65 63 74 45 6e 74 72 79 29 20 2a  RedirectEntry) *
23600 20 70 2d 3e 72 65 64 69 72 65 63 74 2e 6e 0a 20   p->redirect.n. 
23610 20 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20             );.  
23620 20 20 20 20 20 20 70 2d 3e 72 65 64 69 72 65 63        p->redirec
23630 74 2e 61 5b 30 5d 2e 69 46 72 6f 6d 20 3d 20 69  t.a[0].iFrom = i
23640 46 72 6f 6d 3b 0a 20 20 20 20 20 20 20 20 70 2d  From;.        p-
23650 3e 72 65 64 69 72 65 63 74 2e 61 5b 30 5d 2e 69  >redirect.a[0].i
23660 54 6f 20 3d 20 69 54 6f 3b 0a 20 20 20 20 20 20  To = iTo;.      
23670 20 20 70 2d 3e 72 65 64 69 72 65 63 74 2e 6e 2b    p->redirect.n+
23680 2b 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  +;.      }else{.
23690 20 20 20 20 20 20 20 20 2f 2a 20 42 6c 6f 63 6b          /* Block
236a0 20 69 46 72 6f 6d 20 77 61 73 20 61 6c 72 65 61   iFrom was alrea
236b0 64 79 20 72 65 64 69 72 65 63 74 65 64 2e 20 4f  dy redirected. O
236c0 76 65 72 77 72 69 74 65 20 65 78 69 73 74 69 6e  verwrite existin
236d0 67 20 65 6e 74 72 79 2e 20 2a 2f 0a 20 20 20 20  g entry. */.    
236e0 20 20 20 20 70 2d 3e 72 65 64 69 72 65 63 74 2e      p->redirect.
236f0 61 5b 69 5d 2e 69 54 6f 20 3d 20 69 54 6f 3b 0a  a[i].iTo = iTo;.
23700 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 72        }..      r
23710 63 20 3d 20 6c 73 6d 42 6c 6f 63 6b 46 72 65 65  c = lsmBlockFree
23720 28 70 44 62 2c 20 69 46 72 6f 6d 29 3b 0a 0a 20  (pDb, iFrom);.. 
23730 20 20 20 20 20 2a 70 6e 57 72 69 74 65 20 3d 20       *pnWrite = 
23740 6c 73 6d 46 73 42 6c 6f 63 6b 53 69 7a 65 28 70  lsmFsBlockSize(p
23750 44 62 2d 3e 70 46 53 29 20 2f 20 6c 73 6d 46 73  Db->pFS) / lsmFs
23760 50 61 67 65 53 69 7a 65 28 70 44 62 2d 3e 70 46  PageSize(pDb->pF
23770 53 29 3b 0a 20 20 20 20 20 20 70 4c 76 6c 2d 3e  S);.      pLvl->
23780 6c 68 73 2e 70 52 65 64 69 72 65 63 74 20 3d 20  lhs.pRedirect = 
23790 26 70 2d 3e 72 65 64 69 72 65 63 74 3b 0a 20 20  &p->redirect;.  
237a0 20 20 7d 0a 20 20 7d 0a 0a 23 69 66 20 4c 53 4d    }.  }..#if LSM
237b0 5f 4c 4f 47 5f 53 54 52 55 43 54 55 52 45 0a 20  _LOG_STRUCTURE. 
237c0 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
237d0 29 7b 0a 20 20 20 20 63 68 61 72 20 61 42 75 66  ){.    char aBuf
237e0 5b 36 34 5d 3b 0a 20 20 20 20 73 70 72 69 6e 74  [64];.    sprint
237f0 66 28 61 42 75 66 2c 20 22 6d 6f 76 65 2d 62 6c  f(aBuf, "move-bl
23800 6f 63 6b 20 25 64 2f 25 64 22 2c 20 70 2d 3e 72  ock %d/%d", p->r
23810 65 64 69 72 65 63 74 2e 6e 2d 31 2c 20 4c 53 4d  edirect.n-1, LSM
23820 5f 4d 41 58 5f 42 4c 4f 43 4b 5f 52 45 44 49 52  _MAX_BLOCK_REDIR
23830 45 43 54 53 29 3b 0a 20 20 20 20 6c 73 6d 53 6f  ECTS);.    lsmSo
23840 72 74 65 64 44 75 6d 70 53 74 72 75 63 74 75 72  rtedDumpStructur
23850 65 28 70 44 62 2c 20 70 44 62 2d 3e 70 57 6f 72  e(pDb, pDb->pWor
23860 6b 65 72 2c 20 4c 53 4d 5f 4c 4f 47 5f 44 41 54  ker, LSM_LOG_DAT
23870 41 2c 20 30 2c 20 61 42 75 66 29 3b 0a 20 20 7d  A, 0, aBuf);.  }
23880 0a 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72 6e  .#endif.  return
23890 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2f 0a 73 74   rc;.}../*.*/.st
238a0 61 74 69 63 20 69 6e 74 20 6d 65 72 67 65 49 6e  atic int mergeIn
238b0 73 65 72 74 46 72 65 65 6c 69 73 74 53 65 67 6d  sertFreelistSegm
238c0 65 6e 74 73 28 0a 20 20 6c 73 6d 5f 64 62 20 2a  ents(.  lsm_db *
238d0 70 44 62 2c 20 0a 20 20 69 6e 74 20 6e 46 72 65  pDb, .  int nFre
238e0 65 2c 0a 20 20 4d 65 72 67 65 57 6f 72 6b 65 72  e,.  MergeWorker
238f0 20 2a 70 4d 57 0a 29 7b 0a 20 20 69 6e 74 20 72   *pMW.){.  int r
23900 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 69 66  c = LSM_OK;.  if
23910 28 20 6e 46 72 65 65 3e 30 20 29 7b 0a 20 20 20  ( nFree>0 ){.   
23920 20 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 70 43   MultiCursor *pC
23930 73 72 20 3d 20 70 4d 57 2d 3e 70 43 73 72 3b 0a  sr = pMW->pCsr;.
23940 20 20 20 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 20      Level *pLvl 
23950 3d 20 70 4d 57 2d 3e 70 4c 65 76 65 6c 3b 0a 20  = pMW->pLevel;. 
23960 20 20 20 53 65 67 6d 65 6e 74 50 74 72 20 2a 61     SegmentPtr *a
23970 4e 65 77 31 3b 0a 20 20 20 20 53 65 67 6d 65 6e  New1;.    Segmen
23980 74 20 2a 61 4e 65 77 32 3b 0a 0a 20 20 20 20 4c  t *aNew2;..    L
23990 65 76 65 6c 20 2a 70 49 74 65 72 3b 0a 20 20 20  evel *pIter;.   
239a0 20 4c 65 76 65 6c 20 2a 70 4e 65 78 74 3b 0a 20   Level *pNext;. 
239b0 20 20 20 69 6e 74 20 69 20 3d 20 30 3b 0a 0a 20     int i = 0;.. 
239c0 20 20 20 61 4e 65 77 31 20 3d 20 28 53 65 67 6d     aNew1 = (Segm
239d0 65 6e 74 50 74 72 20 2a 29 6c 73 6d 4d 61 6c 6c  entPtr *)lsmMall
239e0 6f 63 5a 65 72 6f 52 63 28 0a 20 20 20 20 20 20  ocZeroRc(.      
239f0 20 20 70 44 62 2d 3e 70 45 6e 76 2c 20 73 69 7a    pDb->pEnv, siz
23a00 65 6f 66 28 53 65 67 6d 65 6e 74 50 74 72 29 20  eof(SegmentPtr) 
23a10 2a 20 28 70 43 73 72 2d 3e 6e 50 74 72 2b 6e 46  * (pCsr->nPtr+nF
23a20 72 65 65 29 2c 20 26 72 63 0a 20 20 20 20 29 3b  ree), &rc.    );
23a30 0a 20 20 20 20 69 66 28 20 72 63 20 29 20 72 65  .    if( rc ) re
23a40 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 6d 65 6d  turn rc;.    mem
23a50 63 70 79 28 26 61 4e 65 77 31 5b 6e 46 72 65 65  cpy(&aNew1[nFree
23a60 5d 2c 20 70 43 73 72 2d 3e 61 50 74 72 2c 20 73  ], pCsr->aPtr, s
23a70 69 7a 65 6f 66 28 53 65 67 6d 65 6e 74 50 74 72  izeof(SegmentPtr
23a80 29 2a 70 43 73 72 2d 3e 6e 50 74 72 29 3b 0a 20  )*pCsr->nPtr);. 
23a90 20 20 20 70 43 73 72 2d 3e 6e 50 74 72 20 2b 3d     pCsr->nPtr +=
23aa0 20 6e 46 72 65 65 3b 0a 20 20 20 20 6c 73 6d 46   nFree;.    lsmF
23ab0 72 65 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70  ree(pDb->pEnv, p
23ac0 43 73 72 2d 3e 61 54 72 65 65 29 3b 0a 20 20 20  Csr->aTree);.   
23ad0 20 6c 73 6d 46 72 65 65 28 70 44 62 2d 3e 70 45   lsmFree(pDb->pE
23ae0 6e 76 2c 20 70 43 73 72 2d 3e 61 50 74 72 29 3b  nv, pCsr->aPtr);
23af0 0a 20 20 20 20 70 43 73 72 2d 3e 61 54 72 65 65  .    pCsr->aTree
23b00 20 3d 20 30 3b 0a 20 20 20 20 70 43 73 72 2d 3e   = 0;.    pCsr->
23b10 61 50 74 72 20 3d 20 61 4e 65 77 31 3b 0a 0a 20  aPtr = aNew1;.. 
23b20 20 20 20 61 4e 65 77 32 20 3d 20 28 53 65 67 6d     aNew2 = (Segm
23b30 65 6e 74 20 2a 29 6c 73 6d 4d 61 6c 6c 6f 63 5a  ent *)lsmMallocZ
23b40 65 72 6f 52 63 28 0a 20 20 20 20 20 20 20 20 70  eroRc(.        p
23b50 44 62 2d 3e 70 45 6e 76 2c 20 73 69 7a 65 6f 66  Db->pEnv, sizeof
23b60 28 53 65 67 6d 65 6e 74 29 20 2a 20 28 70 4c 76  (Segment) * (pLv
23b70 6c 2d 3e 6e 52 69 67 68 74 2b 6e 46 72 65 65 29  l->nRight+nFree)
23b80 2c 20 26 72 63 0a 20 20 20 20 29 3b 0a 20 20 20  , &rc.    );.   
23b90 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e   if( rc ) return
23ba0 20 72 63 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28   rc;.    memcpy(
23bb0 26 61 4e 65 77 32 5b 6e 46 72 65 65 5d 2c 20 70  &aNew2[nFree], p
23bc0 4c 76 6c 2d 3e 61 52 68 73 2c 20 73 69 7a 65 6f  Lvl->aRhs, sizeo
23bd0 66 28 53 65 67 6d 65 6e 74 29 2a 70 4c 76 6c 2d  f(Segment)*pLvl-
23be0 3e 6e 52 69 67 68 74 29 3b 0a 20 20 20 20 70 4c  >nRight);.    pL
23bf0 76 6c 2d 3e 6e 52 69 67 68 74 20 2b 3d 20 6e 46  vl->nRight += nF
23c00 72 65 65 3b 0a 20 20 20 20 6c 73 6d 46 72 65 65  ree;.    lsmFree
23c10 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70 4c 76 6c  (pDb->pEnv, pLvl
23c20 2d 3e 61 52 68 73 29 3b 0a 20 20 20 20 70 4c 76  ->aRhs);.    pLv
23c30 6c 2d 3e 61 52 68 73 20 3d 20 61 4e 65 77 32 3b  l->aRhs = aNew2;
23c40 0a 0a 20 20 20 20 66 6f 72 28 70 49 74 65 72 3d  ..    for(pIter=
23c50 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2d 3e 70 4c  pDb->pWorker->pL
23c60 65 76 65 6c 3b 20 72 63 3d 3d 4c 53 4d 5f 4f 4b  evel; rc==LSM_OK
23c70 20 26 26 20 70 49 74 65 72 21 3d 70 4c 76 6c 3b   && pIter!=pLvl;
23c80 20 70 49 74 65 72 3d 70 4e 65 78 74 29 7b 0a 20   pIter=pNext){. 
23c90 20 20 20 20 20 53 65 67 6d 65 6e 74 20 2a 70 53       Segment *pS
23ca0 65 67 20 3d 20 26 70 4c 76 6c 2d 3e 61 52 68 73  eg = &pLvl->aRhs
23cb0 5b 69 5d 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70  [i];.      memcp
23cc0 79 28 70 53 65 67 2c 20 26 70 49 74 65 72 2d 3e  y(pSeg, &pIter->
23cd0 6c 68 73 2c 20 73 69 7a 65 6f 66 28 53 65 67 6d  lhs, sizeof(Segm
23ce0 65 6e 74 29 29 3b 0a 0a 20 20 20 20 20 20 70 43  ent));..      pC
23cf0 73 72 2d 3e 61 50 74 72 5b 69 5d 2e 70 53 65 67  sr->aPtr[i].pSeg
23d00 20 3d 20 70 53 65 67 3b 0a 20 20 20 20 20 20 70   = pSeg;.      p
23d10 43 73 72 2d 3e 61 50 74 72 5b 69 5d 2e 70 4c 65  Csr->aPtr[i].pLe
23d20 76 65 6c 20 3d 20 70 4c 76 6c 3b 0a 20 20 20 20  vel = pLvl;.    
23d30 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 50 74    rc = segmentPt
23d40 72 45 6e 64 28 70 43 73 72 2c 20 26 70 43 73 72  rEnd(pCsr, &pCsr
23d50 2d 3e 61 50 74 72 5b 69 5d 2c 20 30 29 3b 0a 0a  ->aPtr[i], 0);..
23d60 20 20 20 20 20 20 70 44 62 2d 3e 70 57 6f 72 6b        pDb->pWork
23d70 65 72 2d 3e 70 4c 65 76 65 6c 20 3d 20 70 4e 65  er->pLevel = pNe
23d80 78 74 20 3d 20 70 49 74 65 72 2d 3e 70 4e 65 78  xt = pIter->pNex
23d90 74 3b 0a 20 20 20 20 20 20 73 6f 72 74 65 64 46  t;.      sortedF
23da0 72 65 65 4c 65 76 65 6c 28 70 44 62 2d 3e 70 45  reeLevel(pDb->pE
23db0 6e 76 2c 20 70 49 74 65 72 29 3b 0a 20 20 20 20  nv, pIter);.    
23dc0 20 20 69 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20    i++;.    }.   
23dd0 20 61 73 73 65 72 74 28 20 69 3d 3d 6e 46 72 65   assert( i==nFre
23de0 65 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  e );.    assert(
23df0 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 70   rc!=LSM_OK || p
23e00 44 62 2d 3e 70 57 6f 72 6b 65 72 2d 3e 70 4c 65  Db->pWorker->pLe
23e10 76 65 6c 3d 3d 70 4c 76 6c 20 29 3b 0a 0a 20 20  vel==pLvl );..  
23e20 20 20 66 6f 72 28 69 3d 6e 46 72 65 65 3b 20 69    for(i=nFree; i
23e30 3c 70 43 73 72 2d 3e 6e 50 74 72 3b 20 69 2b 2b  <pCsr->nPtr; i++
23e40 29 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 61  ){.      pCsr->a
23e50 50 74 72 5b 69 5d 2e 70 53 65 67 20 3d 20 26 70  Ptr[i].pSeg = &p
23e60 4c 76 6c 2d 3e 61 52 68 73 5b 69 5d 3b 0a 20 20  Lvl->aRhs[i];.  
23e70 20 20 7d 0a 0a 20 20 20 20 6c 73 6d 46 72 65 65    }..    lsmFree
23e80 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70 4d 57 2d  (pDb->pEnv, pMW-
23e90 3e 61 47 6f 62 62 6c 65 29 3b 0a 20 20 20 20 70  >aGobble);.    p
23ea0 4d 57 2d 3e 61 47 6f 62 62 6c 65 20 3d 20 30 3b  MW->aGobble = 0;
23eb0 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
23ec0 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
23ed0 73 6f 72 74 65 64 57 6f 72 6b 28 0a 20 20 6c 73  sortedWork(.  ls
23ee0 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20 20 20 20  m_db *pDb,      
23ef0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
23f00 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65   Database handle
23f10 2e 20 4d 75 73 74 20 62 65 20 77 6f 72 6b 65 72  . Must be worker
23f20 2e 20 2a 2f 0a 20 20 69 6e 74 20 6e 57 6f 72 6b  . */.  int nWork
23f30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
23f40 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
23f50 20 6f 66 20 70 61 67 65 73 20 6f 66 20 77 6f 72   of pages of wor
23f60 6b 20 74 6f 20 64 6f 20 2a 2f 0a 20 20 69 6e 74  k to do */.  int
23f70 20 6e 4d 65 72 67 65 2c 20 20 20 20 20 20 20 20   nMerge,        
23f80 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
23f90 54 72 79 20 74 6f 20 6d 65 72 67 65 20 74 68 69  Try to merge thi
23fa0 73 20 6d 61 6e 79 20 6c 65 76 65 6c 73 20 61 74  s many levels at
23fb0 20 6f 6e 63 65 20 2a 2f 0a 20 20 69 6e 74 20 62   once */.  int b
23fc0 46 6c 75 73 68 2c 20 20 20 20 20 20 20 20 20 20  Flush,          
23fd0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65             /* Se
23fe0 74 20 69 66 20 63 61 6c 6c 20 69 73 20 74 6f 20  t if call is to 
23ff0 6d 61 6b 65 20 72 6f 6f 6d 20 66 6f 72 20 61 20  make room for a 
24000 66 6c 75 73 68 20 2a 2f 0a 20 20 69 6e 74 20 2a  flush */.  int *
24010 70 6e 57 72 69 74 65 20 20 20 20 20 20 20 20 20  pnWrite         
24020 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
24030 54 3a 20 41 63 74 75 61 6c 20 6e 75 6d 62 65 72  T: Actual number
24040 20 6f 66 20 70 61 67 65 73 20 77 72 69 74 74 65   of pages writte
24050 6e 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  n */.){.  int rc
24060 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20   = LSM_OK;      
24070 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
24080 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 69 6e  urn Code */.  in
24090 74 20 6e 52 65 6d 61 69 6e 69 6e 67 20 3d 20 6e  t nRemaining = n
240a0 57 6f 72 6b 3b 20 20 20 20 20 20 20 20 20 2f 2a  Work;         /*
240b0 20 55 6e 69 74 73 20 6f 66 20 77 6f 72 6b 20 74   Units of work t
240c0 6f 20 64 6f 20 62 65 66 6f 72 65 20 72 65 74 75  o do before retu
240d0 72 6e 69 6e 67 20 2a 2f 0a 20 20 53 6e 61 70 73  rning */.  Snaps
240e0 68 6f 74 20 2a 70 57 6f 72 6b 65 72 20 3d 20 70  hot *pWorker = p
240f0 44 62 2d 3e 70 57 6f 72 6b 65 72 3b 0a 0a 20 20  Db->pWorker;..  
24100 61 73 73 65 72 74 28 20 70 57 6f 72 6b 65 72 20  assert( pWorker 
24110 29 3b 0a 20 20 69 66 28 20 6c 73 6d 44 62 53 6e  );.  if( lsmDbSn
24120 61 70 73 68 6f 74 4c 65 76 65 6c 28 70 57 6f 72  apshotLevel(pWor
24130 6b 65 72 29 3d 3d 30 20 29 20 72 65 74 75 72 6e  ker)==0 ) return
24140 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20 20 77 68 69 6c   LSM_OK;..  whil
24150 65 28 20 6e 52 65 6d 61 69 6e 69 6e 67 3e 30 20  e( nRemaining>0 
24160 29 7b 0a 20 20 20 20 4c 65 76 65 6c 20 2a 70 4c  ){.    Level *pL
24170 65 76 65 6c 20 3d 20 30 3b 0a 0a 20 20 20 20 2f  evel = 0;..    /
24180 2a 20 46 69 6e 64 20 61 20 6c 65 76 65 6c 20 74  * Find a level t
24190 6f 20 77 6f 72 6b 20 6f 6e 2e 20 2a 2f 0a 20 20  o work on. */.  
241a0 20 20 72 63 20 3d 20 73 6f 72 74 65 64 53 65 6c    rc = sortedSel
241b0 65 63 74 4c 65 76 65 6c 28 70 44 62 2c 20 6e 4d  ectLevel(pDb, nM
241c0 65 72 67 65 2c 20 26 70 4c 65 76 65 6c 29 3b 0a  erge, &pLevel);.
241d0 20 20 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d      assert( rc==
241e0 4c 53 4d 5f 4f 4b 20 7c 7c 20 70 4c 65 76 65 6c  LSM_OK || pLevel
241f0 3d 3d 30 20 29 3b 0a 0a 20 20 20 20 69 66 28 20  ==0 );..    if( 
24200 70 4c 65 76 65 6c 3d 3d 30 20 29 7b 0a 20 20 20  pLevel==0 ){.   
24210 20 20 20 69 6e 74 20 6e 44 6f 6e 65 20 3d 20 30     int nDone = 0
24220 3b 0a 20 20 20 20 20 20 4c 65 76 65 6c 20 2a 70  ;.      Level *p
24230 54 6f 70 4c 65 76 65 6c 20 3d 20 6c 73 6d 44 62  TopLevel = lsmDb
24240 53 6e 61 70 73 68 6f 74 4c 65 76 65 6c 28 70 44  SnapshotLevel(pD
24250 62 2d 3e 70 57 6f 72 6b 65 72 29 3b 0a 20 20 20  b->pWorker);.   
24260 20 20 20 69 66 28 20 62 46 6c 75 73 68 3d 3d 30     if( bFlush==0
24270 20 26 26 20 6e 4d 65 72 67 65 3d 3d 31 20 26 26   && nMerge==1 &&
24280 20 70 54 6f 70 4c 65 76 65 6c 20 26 26 20 70 54   pTopLevel && pT
24290 6f 70 4c 65 76 65 6c 2d 3e 70 4e 65 78 74 3d 3d  opLevel->pNext==
242a0 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  0 ){.        rc 
242b0 3d 20 73 6f 72 74 65 64 4d 6f 76 65 42 6c 6f 63  = sortedMoveBloc
242c0 6b 28 70 44 62 2c 20 26 6e 44 6f 6e 65 29 3b 0a  k(pDb, &nDone);.
242d0 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 6e 52        }.      nR
242e0 65 6d 61 69 6e 69 6e 67 20 2d 3d 20 6e 44 6f 6e  emaining -= nDon
242f0 65 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 43 6f 75  e;..      /* Cou
24300 6c 64 20 6e 6f 74 20 66 69 6e 64 20 61 6e 79 20  ld not find any 
24310 77 6f 72 6b 20 74 6f 20 64 6f 2e 20 46 69 6e 69  work to do. Fini
24320 73 68 65 64 2e 20 2a 2f 0a 20 20 20 20 20 20 69  shed. */.      i
24330 66 28 20 6e 44 6f 6e 65 3d 3d 30 20 29 20 62 72  f( nDone==0 ) br
24340 65 61 6b 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  eak;.    }else{.
24350 20 20 20 20 20 20 69 6e 74 20 62 53 61 76 65 20        int bSave 
24360 3d 20 30 3b 0a 20 20 20 20 20 20 46 72 65 65 6c  = 0;.      Freel
24370 69 73 74 20 66 72 65 65 6c 69 73 74 20 3d 20 7b  ist freelist = {
24380 30 2c 20 30 2c 20 30 7d 3b 0a 20 20 20 20 20 20  0, 0, 0};.      
24390 4d 65 72 67 65 57 6f 72 6b 65 72 20 6d 65 72 67  MergeWorker merg
243a0 65 77 6f 72 6b 65 72 3b 20 20 20 20 2f 2a 20 53  eworker;    /* S
243b0 74 61 74 65 20 75 73 65 64 20 74 6f 20 77 6f 72  tate used to wor
243c0 6b 20 6f 6e 20 74 68 65 20 6c 65 76 65 6c 20 6d  k on the level m
243d0 65 72 67 65 20 2a 2f 0a 0a 20 20 20 20 20 20 61  erge */..      a
243e0 73 73 65 72 74 28 20 70 44 62 2d 3e 62 49 6e 63  ssert( pDb->bInc
243f0 72 4d 65 72 67 65 3d 3d 30 20 29 3b 0a 20 20 20  rMerge==0 );.   
24400 20 20 20 61 73 73 65 72 74 28 20 70 44 62 2d 3e     assert( pDb->
24410 70 46 72 65 65 6c 69 73 74 3d 3d 30 20 26 26 20  pFreelist==0 && 
24420 70 44 62 2d 3e 62 55 73 65 46 72 65 65 6c 69 73  pDb->bUseFreelis
24430 74 3d 3d 30 20 29 3b 0a 0a 20 20 20 20 20 20 70  t==0 );..      p
24440 44 62 2d 3e 62 49 6e 63 72 4d 65 72 67 65 20 3d  Db->bIncrMerge =
24450 20 31 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 6d   1;.      rc = m
24460 65 72 67 65 57 6f 72 6b 65 72 49 6e 69 74 28 70  ergeWorkerInit(p
24470 44 62 2c 20 70 4c 65 76 65 6c 2c 20 26 6d 65 72  Db, pLevel, &mer
24480 67 65 77 6f 72 6b 65 72 29 3b 0a 20 20 20 20 20  geworker);.     
24490 20 61 73 73 65 72 74 28 20 6d 65 72 67 65 77 6f   assert( mergewo
244a0 72 6b 65 72 2e 6e 57 6f 72 6b 3d 3d 30 20 29 3b  rker.nWork==0 );
244b0 0a 20 20 20 20 20 20 0a 20 20 20 20 20 20 77 68  .      .      wh
244c0 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20  ile( rc==LSM_OK 
244d0 0a 20 20 20 20 20 20 20 20 20 20 26 26 20 30 3d  .          && 0=
244e0 3d 6d 65 72 67 65 57 6f 72 6b 65 72 44 6f 6e 65  =mergeWorkerDone
244f0 28 26 6d 65 72 67 65 77 6f 72 6b 65 72 29 20 0a  (&mergeworker) .
24500 20 20 20 20 20 20 20 20 20 20 26 26 20 28 6d 65            && (me
24510 72 67 65 77 6f 72 6b 65 72 2e 6e 57 6f 72 6b 3c  rgeworker.nWork<
24520 6e 52 65 6d 61 69 6e 69 6e 67 20 7c 7c 20 70 44  nRemaining || pD
24530 62 2d 3e 62 55 73 65 46 72 65 65 6c 69 73 74 29  b->bUseFreelist)
24540 0a 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20  .      ){.      
24550 20 20 69 6e 74 20 65 54 79 70 65 20 3d 20 72 74    int eType = rt
24560 54 6f 70 69 63 28 6d 65 72 67 65 77 6f 72 6b 65  Topic(mergeworke
24570 72 2e 70 43 73 72 2d 3e 65 54 79 70 65 29 3b 0a  r.pCsr->eType);.
24580 20 20 20 20 20 20 20 20 72 63 20 3d 20 6d 65 72          rc = mer
24590 67 65 57 6f 72 6b 65 72 53 74 65 70 28 26 6d 65  geWorkerStep(&me
245a0 72 67 65 77 6f 72 6b 65 72 29 3b 0a 0a 20 20 20  rgeworker);..   
245b0 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 63       /* If the c
245c0 75 72 73 6f 72 20 6e 6f 77 20 70 6f 69 6e 74 73  ursor now points
245d0 20 61 74 20 74 68 65 20 66 69 72 73 74 20 65 6e   at the first en
245e0 74 72 79 20 70 61 73 74 20 74 68 65 20 65 6e 64  try past the end
245f0 20 6f 66 20 74 68 65 0a 20 20 20 20 20 20 20 20   of the.        
24600 2a 2a 20 75 73 65 72 20 64 61 74 61 20 28 69 2e  ** user data (i.
24610 65 2e 20 65 69 74 68 65 72 20 74 6f 20 45 4f 46  e. either to EOF
24620 20 6f 72 20 74 6f 20 74 68 65 20 66 69 72 73 74   or to the first
24630 20 66 72 65 65 2d 6c 69 73 74 20 65 6e 74 72 79   free-list entry
24640 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 68 61 74  .        ** that
24650 20 77 69 6c 6c 20 62 65 20 61 64 64 65 64 20 74   will be added t
24660 6f 20 74 68 65 20 72 75 6e 29 2c 20 74 68 65 6e  o the run), then
24670 20 63 68 65 63 6b 20 69 66 20 69 74 20 69 73 20   check if it is 
24680 70 6f 73 73 69 62 6c 65 20 74 6f 0a 20 20 20 20  possible to.    
24690 20 20 20 20 2a 2a 20 6d 65 72 67 65 20 69 6e 20      ** merge in 
246a0 61 6e 79 20 66 72 65 65 2d 6c 69 73 74 20 65 6e  any free-list en
246b0 74 72 69 65 73 20 74 68 61 74 20 61 72 65 20 65  tries that are e
246c0 69 74 68 65 72 20 69 6e 2d 6d 65 6d 6f 72 79 20  ither in-memory 
246d0 6f 72 20 69 6e 0a 20 20 20 20 20 20 20 20 2a 2a  or in.        **
246e0 20 66 72 65 65 2d 6c 69 73 74 2d 6f 6e 6c 79 20   free-list-only 
246f0 62 6c 6f 63 6b 73 2e 20 20 2a 2f 0a 20 20 20 20  blocks.  */.    
24700 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f      if( rc==LSM_
24710 4f 4b 20 26 26 20 6e 4d 65 72 67 65 3d 3d 31 20  OK && nMerge==1 
24720 26 26 20 65 54 79 70 65 3d 3d 30 0a 20 20 20 20  && eType==0.    
24730 20 20 20 20 20 26 26 20 28 72 74 54 6f 70 69 63       && (rtTopic
24740 28 6d 65 72 67 65 77 6f 72 6b 65 72 2e 70 43 73  (mergeworker.pCs
24750 72 2d 3e 65 54 79 70 65 29 20 7c 7c 20 6d 65 72  r->eType) || mer
24760 67 65 57 6f 72 6b 65 72 44 6f 6e 65 28 26 6d 65  geWorkerDone(&me
24770 72 67 65 77 6f 72 6b 65 72 29 29 0a 20 20 20 20  rgeworker)).    
24780 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20      ){.         
24790 20 69 6e 74 20 6e 46 72 65 65 20 3d 20 30 3b 20   int nFree = 0; 
247a0 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
247b0 65 72 20 6f 66 20 66 72 65 65 2d 6c 69 73 74 2d  er of free-list-
247c0 6f 6e 6c 79 20 6c 65 76 65 6c 73 20 74 6f 20 6d  only levels to m
247d0 65 72 67 65 20 2a 2f 0a 20 20 20 20 20 20 20 20  erge */.        
247e0 20 20 4c 65 76 65 6c 20 2a 70 4c 76 6c 3b 0a 20    Level *pLvl;. 
247f0 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
24800 20 70 44 62 2d 3e 70 46 72 65 65 6c 69 73 74 3d   pDb->pFreelist=
24810 3d 30 20 26 26 20 70 44 62 2d 3e 62 55 73 65 46  =0 && pDb->bUseF
24820 72 65 65 6c 69 73 74 3d 3d 30 20 29 3b 0a 0a 20  reelist==0 );.. 
24830 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 77 20           /* Now 
24840 63 68 65 63 6b 20 69 66 20 61 6c 6c 20 6c 65 76  check if all lev
24850 65 6c 73 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64  els containing d
24860 61 74 61 20 6e 65 77 65 72 20 74 68 61 6e 20 74  ata newer than t
24870 68 69 73 20 6f 6e 65 0a 20 20 20 20 20 20 20 20  his one.        
24880 20 20 2a 2a 20 61 72 65 20 73 69 6e 67 6c 65 2d    ** are single-
24890 73 65 67 6d 65 6e 74 20 66 72 65 65 2d 6c 69 73  segment free-lis
248a0 74 20 6f 6e 6c 79 20 6c 65 76 65 6c 73 2e 20 49  t only levels. I
248b0 66 20 73 6f 2c 20 74 68 65 79 20 77 69 6c 6c 20  f so, they will 
248c0 62 65 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20  be.          ** 
248d0 6d 65 72 67 65 64 20 69 6e 20 6e 6f 77 2e 20 20  merged in now.  
248e0 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 66 6f 72  */.          for
248f0 28 70 4c 76 6c 3d 70 44 62 2d 3e 70 57 6f 72 6b  (pLvl=pDb->pWork
24900 65 72 2d 3e 70 4c 65 76 65 6c 3b 20 0a 20 20 20  er->pLevel; .   
24910 20 20 20 20 20 20 20 20 20 20 20 70 4c 76 6c 21             pLvl!
24920 3d 6d 65 72 67 65 77 6f 72 6b 65 72 2e 70 4c 65  =mergeworker.pLe
24930 76 65 6c 20 26 26 20 28 70 4c 76 6c 2d 3e 66 6c  vel && (pLvl->fl
24940 61 67 73 20 26 20 4c 45 56 45 4c 5f 46 52 45 45  ags & LEVEL_FREE
24950 4c 49 53 54 5f 4f 4e 4c 59 29 3b 20 0a 20 20 20  LIST_ONLY); .   
24960 20 20 20 20 20 20 20 20 20 20 20 70 4c 76 6c 3d             pLvl=
24970 70 4c 76 6c 2d 3e 70 4e 65 78 74 0a 20 20 20 20  pLvl->pNext.    
24980 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20        ){.       
24990 20 20 20 20 20 61 73 73 65 72 74 28 20 70 4c 76       assert( pLv
249a0 6c 2d 3e 6e 52 69 67 68 74 3d 3d 30 20 29 3b 0a  l->nRight==0 );.
249b0 20 20 20 20 20 20 20 20 20 20 20 20 6e 46 72 65              nFre
249c0 65 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  e++;.          }
249d0 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 70  .          if( p
249e0 4c 76 6c 3d 3d 6d 65 72 67 65 77 6f 72 6b 65 72  Lvl==mergeworker
249f0 2e 70 4c 65 76 65 6c 20 29 7b 0a 0a 20 20 20 20  .pLevel ){..    
24a00 20 20 20 20 20 20 20 20 72 63 20 3d 20 6d 65 72          rc = mer
24a10 67 65 49 6e 73 65 72 74 46 72 65 65 6c 69 73 74  geInsertFreelist
24a20 53 65 67 6d 65 6e 74 73 28 70 44 62 2c 20 6e 46  Segments(pDb, nF
24a30 72 65 65 2c 20 26 6d 65 72 67 65 77 6f 72 6b 65  ree, &mergeworke
24a40 72 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  r);.            
24a50 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
24a60 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  {.              
24a70 72 63 20 3d 20 6d 75 6c 74 69 43 75 72 73 6f 72  rc = multiCursor
24a80 56 69 73 69 74 46 72 65 65 6c 69 73 74 28 6d 65  VisitFreelist(me
24a90 72 67 65 77 6f 72 6b 65 72 2e 70 43 73 72 29 3b  rgeworker.pCsr);
24aa0 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20  .            }. 
24ab0 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20 72             if( r
24ac0 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
24ad0 20 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20             rc = 
24ae0 6d 75 6c 74 69 43 75 72 73 6f 72 53 65 74 75 70  multiCursorSetup
24af0 54 72 65 65 28 6d 65 72 67 65 77 6f 72 6b 65 72  Tree(mergeworker
24b00 2e 70 43 73 72 2c 20 30 29 3b 0a 20 20 20 20 20  .pCsr, 0);.     
24b10 20 20 20 20 20 20 20 20 20 70 44 62 2d 3e 70 46           pDb->pF
24b20 72 65 65 6c 69 73 74 20 3d 20 26 66 72 65 65 6c  reelist = &freel
24b30 69 73 74 3b 0a 20 20 20 20 20 20 20 20 20 20 20  ist;.           
24b40 20 20 20 70 44 62 2d 3e 62 55 73 65 46 72 65 65     pDb->bUseFree
24b50 6c 69 73 74 20 3d 20 31 3b 0a 20 20 20 20 20 20  list = 1;.      
24b60 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
24b70 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20    }.        }.  
24b80 20 20 20 20 7d 0a 20 20 20 20 20 20 6e 52 65 6d      }.      nRem
24b90 61 69 6e 69 6e 67 20 2d 3d 20 4c 53 4d 5f 4d 41  aining -= LSM_MA
24ba0 58 28 6d 65 72 67 65 77 6f 72 6b 65 72 2e 6e 57  X(mergeworker.nW
24bb0 6f 72 6b 2c 20 31 29 3b 0a 0a 20 20 20 20 20 20  ork, 1);..      
24bc0 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
24bd0 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65  {.        /* Che
24be0 63 6b 20 69 66 20 74 68 65 20 6d 65 72 67 65 20  ck if the merge 
24bf0 6f 70 65 72 61 74 69 6f 6e 20 69 73 20 63 6f 6d  operation is com
24c00 70 6c 65 74 65 6c 79 20 66 69 6e 69 73 68 65 64  pletely finished
24c10 2e 20 49 66 20 6e 6f 74 2c 0a 20 20 20 20 20 20  . If not,.      
24c20 20 20 2a 2a 20 67 6f 62 62 6c 65 20 75 70 20 28    ** gobble up (
24c30 64 65 63 6c 61 72 65 20 65 6c 69 67 69 62 6c 65  declare eligible
24c40 20 66 6f 72 20 72 65 63 79 63 6c 69 6e 67 29 20   for recycling) 
24c50 61 6e 79 20 70 61 67 65 73 20 66 72 6f 6d 20 72  any pages from r
24c60 68 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 65  hs.        ** se
24c70 67 6d 65 6e 74 73 20 66 6f 72 20 77 68 69 63 68  gments for which
24c80 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 68 61 73   the content has
24c90 20 62 65 65 6e 20 63 6f 6d 70 6c 65 74 65 6c 79   been completely
24ca0 20 6d 65 72 67 65 64 20 69 6e 74 6f 20 0a 20 20   merged into .  
24cb0 20 20 20 20 20 20 2a 2a 20 74 68 65 20 6c 68 73        ** the lhs
24cc0 20 6f 66 20 74 68 65 20 6c 65 76 65 6c 2e 20 20   of the level.  
24cd0 2a 2f 0a 20 20 20 20 20 20 20 20 69 66 28 20 6d  */.        if( m
24ce0 65 72 67 65 57 6f 72 6b 65 72 44 6f 6e 65 28 26  ergeWorkerDone(&
24cf0 6d 65 72 67 65 77 6f 72 6b 65 72 29 3d 3d 30 20  mergeworker)==0 
24d00 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74  ){.          int
24d10 20 69 3b 0a 20 20 20 20 20 20 20 20 20 20 66 6f   i;.          fo
24d20 72 28 69 3d 30 3b 20 69 3c 70 4c 65 76 65 6c 2d  r(i=0; i<pLevel-
24d30 3e 6e 52 69 67 68 74 3b 20 69 2b 2b 29 7b 0a 20  >nRight; i++){. 
24d40 20 20 20 20 20 20 20 20 20 20 20 53 65 67 6d 65             Segme
24d50 6e 74 50 74 72 20 2a 70 47 6f 62 62 6c 65 20 3d  ntPtr *pGobble =
24d60 20 26 6d 65 72 67 65 77 6f 72 6b 65 72 2e 70 43   &mergeworker.pC
24d70 73 72 2d 3e 61 50 74 72 5b 69 5d 3b 0a 20 20 20  sr->aPtr[i];.   
24d80 20 20 20 20 20 20 20 20 20 69 66 28 20 70 47 6f           if( pGo
24d90 62 62 6c 65 2d 3e 70 53 65 67 2d 3e 69 52 6f 6f  bble->pSeg->iRoo
24da0 74 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  t ){.           
24db0 20 20 20 72 63 20 3d 20 73 6f 72 74 65 64 42 74     rc = sortedBt
24dc0 72 65 65 47 6f 62 62 6c 65 28 70 44 62 2c 20 6d  reeGobble(pDb, m
24dd0 65 72 67 65 77 6f 72 6b 65 72 2e 70 43 73 72 2c  ergeworker.pCsr,
24de0 20 69 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20   i);.           
24df0 20 7d 65 6c 73 65 20 69 66 28 20 6d 65 72 67 65   }else if( merge
24e00 77 6f 72 6b 65 72 2e 61 47 6f 62 62 6c 65 5b 69  worker.aGobble[i
24e10 5d 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  ] ){.           
24e20 20 20 20 6c 73 6d 46 73 47 6f 62 62 6c 65 28 70     lsmFsGobble(p
24e30 44 62 2c 20 70 47 6f 62 62 6c 65 2d 3e 70 53 65  Db, pGobble->pSe
24e40 67 2c 20 26 6d 65 72 67 65 77 6f 72 6b 65 72 2e  g, &mergeworker.
24e50 61 47 6f 62 62 6c 65 5b 69 5d 2c 20 31 29 3b 0a  aGobble[i], 1);.
24e60 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20              }.  
24e70 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
24e80 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
24e90 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20     int i;.      
24ea0 20 20 20 20 69 6e 74 20 62 45 6d 70 74 79 3b 0a      int bEmpty;.
24eb0 20 20 20 20 20 20 20 20 20 20 6d 65 72 67 65 57            mergeW
24ec0 6f 72 6b 65 72 53 68 75 74 64 6f 77 6e 28 26 6d  orkerShutdown(&m
24ed0 65 72 67 65 77 6f 72 6b 65 72 2c 20 26 72 63 29  ergeworker, &rc)
24ee0 3b 0a 20 20 20 20 20 20 20 20 20 20 62 45 6d 70  ;.          bEmp
24ef0 74 79 20 3d 20 28 70 4c 65 76 65 6c 2d 3e 6c 68  ty = (pLevel->lh
24f00 73 2e 69 46 69 72 73 74 3d 3d 30 29 3b 0a 0a 20  s.iFirst==0);.. 
24f10 20 20 20 20 20 20 20 20 20 69 66 28 20 62 45 6d           if( bEm
24f20 70 74 79 3d 3d 30 20 26 26 20 72 63 3d 3d 4c 53  pty==0 && rc==LS
24f30 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  M_OK ){.        
24f40 20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 53 6f      rc = lsmFsSo
24f50 72 74 65 64 46 69 6e 69 73 68 28 70 44 62 2d 3e  rtedFinish(pDb->
24f60 70 46 53 2c 20 26 70 4c 65 76 65 6c 2d 3e 6c 68  pFS, &pLevel->lh
24f70 73 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  s);.          }.
24f80 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 70  .          if( p
24f90 44 62 2d 3e 62 55 73 65 46 72 65 65 6c 69 73 74  Db->bUseFreelist
24fa0 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
24fb0 46 72 65 65 6c 69 73 74 20 2a 70 20 3d 20 26 70  Freelist *p = &p
24fc0 44 62 2d 3e 70 57 6f 72 6b 65 72 2d 3e 66 72 65  Db->pWorker->fre
24fd0 65 6c 69 73 74 3b 0a 20 20 20 20 20 20 20 20 20  elist;.         
24fe0 20 20 20 6c 73 6d 46 72 65 65 28 70 44 62 2d 3e     lsmFree(pDb->
24ff0 70 45 6e 76 2c 20 70 2d 3e 61 45 6e 74 72 79 29  pEnv, p->aEntry)
25000 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 65  ;.            me
25010 6d 63 70 79 28 70 2c 20 26 66 72 65 65 6c 69 73  mcpy(p, &freelis
25020 74 2c 20 73 69 7a 65 6f 66 28 66 72 65 65 6c 69  t, sizeof(freeli
25030 73 74 29 29 3b 0a 20 20 20 20 20 20 20 20 20 20  st));.          
25040 20 20 70 44 62 2d 3e 62 55 73 65 46 72 65 65 6c    pDb->bUseFreel
25050 69 73 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ist = 0;.       
25060 20 20 20 20 20 70 44 62 2d 3e 70 46 72 65 65 6c       pDb->pFreel
25070 69 73 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ist = 0;.       
25080 20 20 20 20 20 62 53 61 76 65 20 3d 20 31 3b 0a       bSave = 1;.
25090 20 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20            }..   
250a0 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20         for(i=0; 
250b0 69 3c 70 4c 65 76 65 6c 2d 3e 6e 52 69 67 68 74  i<pLevel->nRight
250c0 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
250d0 20 20 20 20 6c 73 6d 46 73 53 6f 72 74 65 64 44      lsmFsSortedD
250e0 65 6c 65 74 65 28 70 44 62 2d 3e 70 46 53 2c 20  elete(pDb->pFS, 
250f0 70 57 6f 72 6b 65 72 2c 20 31 2c 20 26 70 4c 65  pWorker, 1, &pLe
25100 76 65 6c 2d 3e 61 52 68 73 5b 69 5d 29 3b 0a 20  vel->aRhs[i]);. 
25110 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20           }..    
25120 20 20 20 20 20 20 69 66 28 20 62 45 6d 70 74 79        if( bEmpty
25130 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
25140 2f 2a 20 49 66 20 74 68 65 20 6e 65 77 20 6c 65  /* If the new le
25150 76 65 6c 20 69 73 20 63 6f 6d 70 6c 65 74 65 6c  vel is completel
25160 79 20 65 6d 70 74 79 2c 20 72 65 6d 6f 76 65 20  y empty, remove 
25170 69 74 20 66 72 6f 6d 20 74 68 65 20 0a 20 20 20  it from the .   
25180 20 20 20 20 20 20 20 20 20 2a 2a 20 64 61 74 61           ** data
25190 62 61 73 65 20 73 6e 61 70 73 68 6f 74 2e 20 54  base snapshot. T
251a0 68 69 73 20 63 61 6e 20 6f 6e 6c 79 20 68 61 70  his can only hap
251b0 70 65 6e 20 69 66 20 61 6c 6c 20 69 6e 70 75 74  pen if all input
251c0 20 6b 65 79 73 20 77 65 72 65 0a 20 20 20 20 20   keys were.     
251d0 20 20 20 20 20 20 20 2a 2a 20 61 6e 6e 69 68 69         ** annihi
251e0 6c 61 74 65 64 2e 20 53 69 6e 63 65 20 6b 65 79  lated. Since key
251f0 73 20 61 72 65 20 6f 6e 6c 79 20 61 6e 6e 69 68  s are only annih
25200 69 6c 61 74 65 64 20 69 66 20 74 68 65 20 6e 65  ilated if the ne
25210 77 20 6c 65 76 65 6c 0a 20 20 20 20 20 20 20 20  w level.        
25220 20 20 20 20 2a 2a 20 69 73 20 74 68 65 20 6c 61      ** is the la
25230 73 74 20 69 6e 20 74 68 65 20 6c 69 6e 6b 65 64  st in the linked
25240 20 6c 69 73 74 20 28 63 6f 6e 74 61 69 6e 73 20   list (contains 
25250 74 68 65 20 6d 6f 73 74 20 61 6e 63 69 65 6e 74  the most ancient
25260 20 6f 66 0a 20 20 20 20 20 20 20 20 20 20 20 20   of.            
25270 2a 2a 20 64 61 74 61 62 61 73 65 20 63 6f 6e 74  ** database cont
25280 65 6e 74 29 2c 20 74 68 69 73 20 67 75 61 72 61  ent), this guara
25290 6e 74 65 65 73 20 74 68 61 74 20 70 4c 65 76 65  ntees that pLeve
252a0 6c 2d 3e 70 4e 65 78 74 3d 3d 30 2e 20 20 2a 2f  l->pNext==0.  */
252b0 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 4c 65   .            Le
252c0 76 65 6c 20 2a 70 54 6f 70 3b 20 20 20 20 20 20  vel *pTop;      
252d0 20 20 20 20 2f 2a 20 54 6f 70 20 6c 65 76 65 6c      /* Top level
252e0 20 6f 66 20 77 6f 72 6b 65 72 20 73 6e 61 70 73   of worker snaps
252f0 68 6f 74 20 2a 2f 0a 20 20 20 20 20 20 20 20 20  hot */.         
25300 20 20 20 4c 65 76 65 6c 20 2a 2a 70 70 3b 20 20     Level **pp;  
25310 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 61 64           /* Read
25320 2f 77 72 69 74 65 20 69 74 65 72 61 74 6f 72 20  /write iterator 
25330 66 6f 72 20 4c 65 76 65 6c 2e 70 4e 65 78 74 20  for Level.pNext 
25340 6c 69 73 74 20 2a 2f 0a 0a 20 20 20 20 20 20 20  list */..       
25350 20 20 20 20 20 61 73 73 65 72 74 28 20 70 4c 65       assert( pLe
25360 76 65 6c 2d 3e 70 4e 65 78 74 3d 3d 30 20 29 3b  vel->pNext==0 );
25370 0a 0a 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ..            /*
25380 20 52 65 6d 6f 76 65 20 74 68 65 20 6c 65 76 65   Remove the leve
25390 6c 20 66 72 6f 6d 20 74 68 65 20 77 6f 72 6b 65  l from the worke
253a0 72 20 73 6e 61 70 73 68 6f 74 2e 20 2a 2f 0a 20  r snapshot. */. 
253b0 20 20 20 20 20 20 20 20 20 20 20 70 54 6f 70 20             pTop 
253c0 3d 20 6c 73 6d 44 62 53 6e 61 70 73 68 6f 74 4c  = lsmDbSnapshotL
253d0 65 76 65 6c 28 70 57 6f 72 6b 65 72 29 3b 0a 20  evel(pWorker);. 
253e0 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 28 70             for(p
253f0 70 3d 26 70 54 6f 70 3b 20 2a 70 70 21 3d 70 4c  p=&pTop; *pp!=pL
25400 65 76 65 6c 3b 20 70 70 3d 26 28 28 2a 70 70 29  evel; pp=&((*pp)
25410 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20 20 20  ->pNext));.     
25420 20 20 20 20 20 20 20 2a 70 70 20 3d 20 70 4c 65         *pp = pLe
25430 76 65 6c 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  vel->pNext;.    
25440 20 20 20 20 20 20 20 20 6c 73 6d 44 62 53 6e 61          lsmDbSna
25450 70 73 68 6f 74 53 65 74 4c 65 76 65 6c 28 70 57  pshotSetLevel(pW
25460 6f 72 6b 65 72 2c 20 70 54 6f 70 29 3b 0a 0a 20  orker, pTop);.. 
25470 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72             /* Fr
25480 65 65 20 74 68 65 20 4c 65 76 65 6c 20 73 74 72  ee the Level str
25490 75 63 74 75 72 65 2e 20 2a 2f 0a 20 20 20 20 20  ucture. */.     
254a0 20 20 20 20 20 20 20 73 6f 72 74 65 64 46 72 65         sortedFre
254b0 65 4c 65 76 65 6c 28 70 44 62 2d 3e 70 45 6e 76  eLevel(pDb->pEnv
254c0 2c 20 70 4c 65 76 65 6c 29 3b 0a 20 20 20 20 20  , pLevel);.     
254d0 20 20 20 20 20 7d 65 6c 73 65 7b 0a 0a 20 20 20       }else{..   
254e0 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72 65 65           /* Free
254f0 20 74 68 65 20 73 65 70 61 72 61 74 6f 72 73 20   the separators 
25500 6f 66 20 74 68 65 20 6e 65 78 74 20 6c 65 76 65  of the next leve
25510 6c 2c 20 69 66 20 72 65 71 75 69 72 65 64 2e 20  l, if required. 
25520 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  */.            i
25530 66 28 20 70 4c 65 76 65 6c 2d 3e 70 4d 65 72 67  f( pLevel->pMerg
25540 65 2d 3e 6e 49 6e 70 75 74 20 3e 20 70 4c 65 76  e->nInput > pLev
25550 65 6c 2d 3e 6e 52 69 67 68 74 20 29 7b 0a 20 20  el->nRight ){.  
25560 20 20 20 20 20 20 20 20 20 20 20 20 61 73 73 65              asse
25570 72 74 28 20 70 4c 65 76 65 6c 2d 3e 70 4e 65 78  rt( pLevel->pNex
25580 74 2d 3e 6c 68 73 2e 69 52 6f 6f 74 20 29 3b 0a  t->lhs.iRoot );.
25590 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 4c                pL
255a0 65 76 65 6c 2d 3e 70 4e 65 78 74 2d 3e 6c 68 73  evel->pNext->lhs
255b0 2e 69 52 6f 6f 74 20 3d 20 30 3b 0a 20 20 20 20  .iRoot = 0;.    
255c0 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
255d0 20 20 20 20 20 20 20 2f 2a 20 5a 65 72 6f 20 74         /* Zero t
255e0 68 65 20 72 69 67 68 74 2d 68 61 6e 64 2d 73 69  he right-hand-si
255f0 64 65 20 6f 66 20 70 4c 65 76 65 6c 20 2a 2f 0a  de of pLevel */.
25600 20 20 20 20 20 20 20 20 20 20 20 20 6c 73 6d 46              lsmF
25610 72 65 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70  ree(pDb->pEnv, p
25620 4c 65 76 65 6c 2d 3e 61 52 68 73 29 3b 0a 20 20  Level->aRhs);.  
25630 20 20 20 20 20 20 20 20 20 20 70 4c 65 76 65 6c            pLevel
25640 2d 3e 6e 52 69 67 68 74 20 3d 20 30 3b 0a 20 20  ->nRight = 0;.  
25650 20 20 20 20 20 20 20 20 20 20 70 4c 65 76 65 6c            pLevel
25660 2d 3e 61 52 68 73 20 3d 20 30 3b 0a 0a 20 20 20  ->aRhs = 0;..   
25670 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72 65 65           /* Free
25680 20 74 68 65 20 4d 65 72 67 65 20 6f 62 6a 65 63   the Merge objec
25690 74 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 20  t */.           
256a0 20 6c 73 6d 46 72 65 65 28 70 44 62 2d 3e 70 45   lsmFree(pDb->pE
256b0 6e 76 2c 20 70 4c 65 76 65 6c 2d 3e 70 4d 65 72  nv, pLevel->pMer
256c0 67 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  ge);.           
256d0 20 70 4c 65 76 65 6c 2d 3e 70 4d 65 72 67 65 20   pLevel->pMerge 
256e0 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  = 0;.          }
256f0 0a 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ..          if( 
25700 62 53 61 76 65 20 26 26 20 72 63 3d 3d 4c 53 4d  bSave && rc==LSM
25710 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20  _OK ){.         
25720 20 20 20 70 44 62 2d 3e 62 49 6e 63 72 4d 65 72     pDb->bIncrMer
25730 67 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  ge = 0;.        
25740 20 20 20 20 72 63 20 3d 20 6c 73 6d 53 61 76 65      rc = lsmSave
25750 57 6f 72 6b 65 72 28 70 44 62 2c 20 30 29 3b 0a  Worker(pDb, 0);.
25760 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
25770 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20      }.      }.. 
25780 20 20 20 20 20 2f 2a 20 43 6c 65 61 6e 20 75 70       /* Clean up
25790 20 74 68 65 20 4d 65 72 67 65 57 6f 72 6b 65 72   the MergeWorker
257a0 20 6f 62 6a 65 63 74 20 69 6e 69 74 69 61 6c 69   object initiali
257b0 7a 65 64 20 61 62 6f 76 65 2e 20 49 66 20 6e 6f  zed above. If no
257c0 20 65 72 72 6f 72 0a 20 20 20 20 20 20 2a 2a 20   error.      ** 
257d0 68 61 73 20 6f 63 63 75 72 72 65 64 2c 20 69 6e  has occurred, in
257e0 76 6f 6b 65 20 74 68 65 20 77 6f 72 6b 2d 68 6f  voke the work-ho
257f0 6f 6b 20 74 6f 20 69 6e 66 6f 72 6d 20 74 68 65  ok to inform the
25800 20 61 70 70 6c 69 63 61 74 69 6f 6e 20 74 68 61   application tha
25810 74 0a 20 20 20 20 20 20 2a 2a 20 74 68 65 20 64  t.      ** the d
25820 61 74 61 62 61 73 65 20 73 74 72 75 63 74 75 72  atabase structur
25830 65 20 68 61 73 20 63 68 61 6e 67 65 64 2e 20 2a  e has changed. *
25840 2f 0a 20 20 20 20 20 20 6d 65 72 67 65 57 6f 72  /.      mergeWor
25850 6b 65 72 53 68 75 74 64 6f 77 6e 28 26 6d 65 72  kerShutdown(&mer
25860 67 65 77 6f 72 6b 65 72 2c 20 26 72 63 29 3b 0a  geworker, &rc);.
25870 20 20 20 20 20 20 70 44 62 2d 3e 62 49 6e 63 72        pDb->bIncr
25880 4d 65 72 67 65 20 3d 20 30 3b 0a 20 20 20 20 20  Merge = 0;.     
25890 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
258a0 29 20 73 6f 72 74 65 64 49 6e 76 6f 6b 65 57 6f  ) sortedInvokeWo
258b0 72 6b 48 6f 6f 6b 28 70 44 62 29 3b 0a 0a 23 69  rkHook(pDb);..#i
258c0 66 20 4c 53 4d 5f 4c 4f 47 5f 53 54 52 55 43 54  f LSM_LOG_STRUCT
258d0 55 52 45 0a 20 20 20 20 20 20 6c 73 6d 53 6f 72  URE.      lsmSor
258e0 74 65 64 44 75 6d 70 53 74 72 75 63 74 75 72 65  tedDumpStructure
258f0 28 70 44 62 2c 20 70 44 62 2d 3e 70 57 6f 72 6b  (pDb, pDb->pWork
25900 65 72 2c 20 4c 53 4d 5f 4c 4f 47 5f 44 41 54 41  er, LSM_LOG_DATA
25910 2c 20 30 2c 20 22 77 6f 72 6b 22 29 3b 0a 23 65  , 0, "work");.#e
25920 6e 64 69 66 0a 20 20 20 20 20 20 61 73 73 65 72  ndif.      asser
25930 74 42 74 72 65 65 4f 6b 28 70 44 62 2c 20 26 70  tBtreeOk(pDb, &p
25940 4c 65 76 65 6c 2d 3e 6c 68 73 29 3b 0a 20 20 20  Level->lhs);.   
25950 20 20 20 61 73 73 65 72 74 52 75 6e 49 6e 4f 72     assertRunInOr
25960 64 65 72 28 70 44 62 2c 20 26 70 4c 65 76 65 6c  der(pDb, &pLevel
25970 2d 3e 6c 68 73 29 3b 0a 0a 20 20 20 20 20 20 2f  ->lhs);..      /
25980 2a 20 49 66 20 62 46 6c 75 73 68 20 69 73 20 74  * If bFlush is t
25990 72 75 65 20 61 6e 64 20 74 68 65 20 64 61 74 61  rue and the data
259a0 62 61 73 65 20 69 73 20 6e 6f 20 6c 6f 6e 67 65  base is no longe
259b0 72 20 63 6f 6e 73 69 64 65 72 65 64 20 22 66 75  r considered "fu
259c0 6c 6c 22 2c 0a 20 20 20 20 20 20 2a 2a 20 62 72  ll",.      ** br
259d0 65 61 6b 20 6f 75 74 20 6f 66 20 74 68 65 20 6c  eak out of the l
259e0 6f 6f 70 20 65 76 65 6e 20 69 66 20 6e 52 65 6d  oop even if nRem
259f0 61 69 6e 69 6e 67 20 69 73 20 73 74 69 6c 6c 20  aining is still 
25a00 67 72 65 61 74 65 72 20 74 68 61 6e 0a 20 20 20  greater than.   
25a10 20 20 20 2a 2a 20 7a 65 72 6f 2e 20 54 68 65 20     ** zero. The 
25a20 63 61 6c 6c 65 72 20 68 61 73 20 61 6e 20 69 6e  caller has an in
25a30 2d 6d 65 6d 6f 72 79 20 74 72 65 65 20 74 6f 20  -memory tree to 
25a40 66 6c 75 73 68 20 74 6f 20 64 69 73 6b 2e 20 20  flush to disk.  
25a50 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 62 46 6c  */.      if( bFl
25a60 75 73 68 20 26 26 20 73 6f 72 74 65 64 44 62 49  ush && sortedDbI
25a70 73 46 75 6c 6c 28 70 44 62 29 3d 3d 30 20 29 20  sFull(pDb)==0 ) 
25a80 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d  break;.    }.  }
25a90 0a 0a 20 20 69 66 28 20 70 6e 57 72 69 74 65 20  ..  if( pnWrite 
25aa0 29 20 2a 70 6e 57 72 69 74 65 20 3d 20 28 6e 57  ) *pnWrite = (nW
25ab0 6f 72 6b 20 2d 20 6e 52 65 6d 61 69 6e 69 6e 67  ork - nRemaining
25ac0 29 3b 0a 20 20 70 57 6f 72 6b 65 72 2d 3e 6e 57  );.  pWorker->nW
25ad0 72 69 74 65 20 2b 3d 20 28 6e 57 6f 72 6b 20 2d  rite += (nWork -
25ae0 20 6e 52 65 6d 61 69 6e 69 6e 67 29 3b 0a 0a 23   nRemaining);..#
25af0 69 66 64 65 66 20 4c 53 4d 5f 4c 4f 47 5f 57 4f  ifdef LSM_LOG_WO
25b00 52 4b 0a 20 20 6c 73 6d 4c 6f 67 4d 65 73 73 61  RK.  lsmLogMessa
25b10 67 65 28 70 44 62 2c 20 72 63 2c 20 22 73 6f 72  ge(pDb, rc, "sor
25b20 74 65 64 57 6f 72 6b 28 29 3a 20 25 64 20 70 61  tedWork(): %d pa
25b30 67 65 73 22 2c 20 28 6e 57 6f 72 6b 2d 6e 52 65  ges", (nWork-nRe
25b40 6d 61 69 6e 69 6e 67 29 29 3b 0a 23 65 6e 64 69  maining));.#endi
25b50 66 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  f.  return rc;.}
25b60 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 64 61 74 61  ../*.** The data
25b70 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  base connection 
25b80 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69  passed as the fi
25b90 72 73 74 20 61 72 67 75 6d 65 6e 74 20 6d 75 73  rst argument mus
25ba0 74 20 62 65 20 61 20 77 6f 72 6b 65 72 0a 2a 2a  t be a worker.**
25bb0 20 63 6f 6e 6e 65 63 74 69 6f 6e 2e 20 54 68 69   connection. Thi
25bc0 73 20 66 75 6e 63 74 69 6f 6e 20 63 68 65 63 6b  s function check
25bd0 73 20 69 66 20 74 68 65 72 65 20 65 78 69 73 74  s if there exist
25be0 73 20 61 6e 20 22 6f 6c 64 22 20 69 6e 2d 6d 65  s an "old" in-me
25bf0 6d 6f 72 79 20 74 72 65 65 0a 2a 2a 20 72 65 61  mory tree.** rea
25c00 64 79 20 74 6f 20 62 65 20 66 6c 75 73 68 65 64  dy to be flushed
25c10 20 74 6f 20 64 69 73 6b 2e 20 49 66 20 73 6f 2c   to disk. If so,
25c20 20 74 72 75 65 20 69 73 20 72 65 74 75 72 6e 65   true is returne
25c30 64 2e 20 4f 74 68 65 72 77 69 73 65 20 66 61 6c  d. Otherwise fal
25c40 73 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20  se..**.** If an 
25c50 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 2a 70  error occurs, *p
25c60 52 63 20 69 73 20 73 65 74 20 74 6f 20 61 6e 20  Rc is set to an 
25c70 4c 53 4d 20 65 72 72 6f 72 20 63 6f 64 65 20 62  LSM error code b
25c80 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
25c90 0a 2a 2a 20 49 74 20 69 73 20 61 73 73 75 6d 65  .** It is assume
25ca0 64 20 74 68 61 74 20 2a 70 52 63 20 69 73 20 73  d that *pRc is s
25cb0 65 74 20 74 6f 20 4c 53 4d 5f 4f 4b 20 77 68 65  et to LSM_OK whe
25cc0 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
25cd0 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74  is called..*/.st
25ce0 61 74 69 63 20 69 6e 74 20 73 6f 72 74 65 64 54  atic int sortedT
25cf0 72 65 65 48 61 73 4f 6c 64 28 6c 73 6d 5f 64 62  reeHasOld(lsm_db
25d00 20 2a 70 44 62 2c 20 69 6e 74 20 2a 70 52 63 29   *pDb, int *pRc)
25d10 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d  {.  int rc = LSM
25d20 5f 4f 4b 3b 0a 20 20 69 6e 74 20 62 52 65 74 20  _OK;.  int bRet 
25d30 3d 20 30 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  = 0;..  assert( 
25d40 70 44 62 2d 3e 70 57 6f 72 6b 65 72 20 29 3b 0a  pDb->pWorker );.
25d50 20 20 69 66 28 20 2a 70 52 63 3d 3d 4c 53 4d 5f    if( *pRc==LSM_
25d60 4f 4b 20 29 7b 0a 20 20 20 20 69 66 28 20 72 63  OK ){.    if( rc
25d70 3d 3d 4c 53 4d 5f 4f 4b 20 0a 20 20 20 20 20 20  ==LSM_OK .      
25d80 20 20 26 26 20 70 44 62 2d 3e 74 72 65 65 68 64    && pDb->treehd
25d90 72 2e 69 4f 6c 64 53 68 6d 69 64 0a 20 20 20 20  r.iOldShmid.    
25da0 20 20 20 20 26 26 20 70 44 62 2d 3e 74 72 65 65      && pDb->tree
25db0 68 64 72 2e 69 4f 6c 64 4c 6f 67 21 3d 70 44 62  hdr.iOldLog!=pDb
25dc0 2d 3e 70 57 6f 72 6b 65 72 2d 3e 69 4c 6f 67 4f  ->pWorker->iLogO
25dd0 66 66 20 0a 20 20 20 20 20 20 29 7b 0a 20 20 20  ff .      ){.   
25de0 20 20 20 62 52 65 74 20 3d 20 31 3b 0a 20 20 20     bRet = 1;.   
25df0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 62 52   }else{.      bR
25e00 65 74 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20  et = 0;.    }.  
25e10 20 20 2a 70 52 63 20 3d 20 72 63 3b 0a 20 20 7d    *pRc = rc;.  }
25e20 0a 20 20 61 73 73 65 72 74 28 20 2a 70 52 63 3d  .  assert( *pRc=
25e30 3d 4c 53 4d 5f 4f 4b 20 7c 7c 20 62 52 65 74 3d  =LSM_OK || bRet=
25e40 3d 30 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 62  =0 );.  return b
25e50 52 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72  Ret;.}../*.** Cr
25e60 65 61 74 65 20 61 20 6e 65 77 20 66 72 65 65 2d  eate a new free-
25e70 6c 69 73 74 20 6f 6e 6c 79 20 74 6f 70 2d 6c 65  list only top-le
25e80 76 65 6c 20 73 65 67 6d 65 6e 74 2e 20 52 65 74  vel segment. Ret
25e90 75 72 6e 20 4c 53 4d 5f 4f 4b 20 69 66 20 73 75  urn LSM_OK if su
25ea0 63 63 65 73 73 66 75 6c 0a 2a 2a 20 6f 72 20 61  ccessful.** or a
25eb0 6e 20 4c 53 4d 20 65 72 72 6f 72 20 63 6f 64 65  n LSM error code
25ec0 20 69 66 20 73 6f 6d 65 20 65 72 72 6f 72 20 6f   if some error o
25ed0 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  ccurs..*/.static
25ee0 20 69 6e 74 20 73 6f 72 74 65 64 4e 65 77 46 72   int sortedNewFr
25ef0 65 65 6c 69 73 74 4f 6e 6c 79 28 6c 73 6d 5f 64  eelistOnly(lsm_d
25f00 62 20 2a 70 44 62 29 7b 0a 20 20 72 65 74 75 72  b *pDb){.  retur
25f10 6e 20 73 6f 72 74 65 64 4e 65 77 54 6f 70 6c 65  n sortedNewTople
25f20 76 65 6c 28 70 44 62 2c 20 54 52 45 45 5f 4e 4f  vel(pDb, TREE_NO
25f30 4e 45 2c 20 30 29 3b 0a 7d 0a 0a 69 6e 74 20 6c  NE, 0);.}..int l
25f40 73 6d 53 61 76 65 57 6f 72 6b 65 72 28 6c 73 6d  smSaveWorker(lsm
25f50 5f 64 62 20 2a 70 44 62 2c 20 69 6e 74 20 62 46  _db *pDb, int bF
25f60 6c 75 73 68 29 7b 0a 20 20 53 6e 61 70 73 68 6f  lush){.  Snapsho
25f70 74 20 2a 70 20 3d 20 70 44 62 2d 3e 70 57 6f 72  t *p = pDb->pWor
25f80 6b 65 72 3b 0a 20 20 69 66 28 20 70 2d 3e 66 72  ker;.  if( p->fr
25f90 65 65 6c 69 73 74 2e 6e 45 6e 74 72 79 3e 70 44  eelist.nEntry>pD
25fa0 62 2d 3e 6e 4d 61 78 46 72 65 65 6c 69 73 74 20  b->nMaxFreelist 
25fb0 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20  ){.    int rc = 
25fc0 73 6f 72 74 65 64 4e 65 77 46 72 65 65 6c 69 73  sortedNewFreelis
25fd0 74 4f 6e 6c 79 28 70 44 62 29 3b 0a 20 20 20 20  tOnly(pDb);.    
25fe0 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29  if( rc!=LSM_OK )
25ff0 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
26000 20 20 72 65 74 75 72 6e 20 6c 73 6d 43 68 65 63    return lsmChec
26010 6b 70 6f 69 6e 74 53 61 76 65 57 6f 72 6b 65 72  kpointSaveWorker
26020 28 70 44 62 2c 20 62 46 6c 75 73 68 29 3b 0a 7d  (pDb, bFlush);.}
26030 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 64 6f 4c  ..static int doL
26040 73 6d 53 69 6e 67 6c 65 57 6f 72 6b 28 0a 20 20  smSingleWork(.  
26050 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 0a 20 20  lsm_db *pDb, .  
26060 69 6e 74 20 62 53 68 75 74 64 6f 77 6e 2c 0a 20  int bShutdown,. 
26070 20 69 6e 74 20 6e 4d 65 72 67 65 2c 20 20 20 20   int nMerge,    
26080 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26090 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 73 65 67 6d   /* Minimum segm
260a0 65 6e 74 73 20 74 6f 20 6d 65 72 67 65 20 74 6f  ents to merge to
260b0 67 65 74 68 65 72 20 2a 2f 0a 20 20 69 6e 74 20  gether */.  int 
260c0 6e 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20  nPage,          
260d0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
260e0 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 74  umber of pages t
260f0 6f 20 77 72 69 74 65 20 74 6f 20 64 69 73 6b 20  o write to disk 
26100 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 57 72 69 74  */.  int *pnWrit
26110 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
26120 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50 61 67       /* OUT: Pag
26130 65 73 20 61 63 74 75 61 6c 6c 79 20 77 72 69 74  es actually writ
26140 74 65 6e 20 74 6f 20 64 69 73 6b 20 2a 2f 0a 20  ten to disk */. 
26150 20 69 6e 74 20 2a 70 62 43 6b 70 74 20 20 20 20   int *pbCkpt    
26160 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26170 20 2f 2a 20 4f 55 54 3a 20 54 72 75 65 20 69 66   /* OUT: True if
26180 20 61 6e 20 61 75 74 6f 2d 63 68 65 63 6b 70 6f   an auto-checkpo
26190 69 6e 74 20 69 73 20 72 65 71 2e 20 2a 2f 0a 29  int is req. */.)
261a0 7b 0a 20 20 53 6e 61 70 73 68 6f 74 20 2a 70 57  {.  Snapshot *pW
261b0 6f 72 6b 65 72 3b 20 20 20 20 20 20 20 20 20 20  orker;          
261c0 20 20 20 20 2f 2a 20 57 6f 72 6b 65 72 20 73 6e      /* Worker sn
261d0 61 70 73 68 6f 74 20 2a 2f 0a 20 20 69 6e 74 20  apshot */.  int 
261e0 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20  rc = LSM_OK;    
261f0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
26200 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
26210 69 6e 74 20 62 44 69 72 74 79 20 3d 20 30 3b 0a  int bDirty = 0;.
26220 20 20 69 6e 74 20 6e 4d 61 78 20 3d 20 6e 50 61    int nMax = nPa
26230 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
26240 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 70 61 67    /* Maximum pag
26250 65 73 20 74 6f 20 77 72 69 74 65 20 74 6f 20 64  es to write to d
26260 69 73 6b 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65  isk */.  int nRe
26270 6d 20 3d 20 6e 50 61 67 65 3b 0a 20 20 69 6e 74  m = nPage;.  int
26280 20 62 43 6b 70 74 20 3d 20 30 3b 0a 0a 20 20 61   bCkpt = 0;..  a
26290 73 73 65 72 74 28 20 6e 50 61 67 65 3e 30 20 29  ssert( nPage>0 )
262a0 3b 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 74 68 65  ;..  /* Open the
262b0 20 77 6f 72 6b 65 72 20 27 74 72 61 6e 73 61 63   worker 'transac
262c0 74 69 6f 6e 27 2e 20 49 74 20 77 69 6c 6c 20 62  tion'. It will b
262d0 65 20 63 6c 6f 73 65 64 20 62 65 66 6f 72 65 20  e closed before 
262e0 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 0a 20 20  this function.  
262f0 2a 2a 20 72 65 74 75 72 6e 73 2e 20 20 2a 2f 0a  ** returns.  */.
26300 20 20 61 73 73 65 72 74 28 20 70 44 62 2d 3e 70    assert( pDb->p
26310 57 6f 72 6b 65 72 3d 3d 30 20 29 3b 0a 20 20 72  Worker==0 );.  r
26320 63 20 3d 20 6c 73 6d 42 65 67 69 6e 57 6f 72 6b  c = lsmBeginWork
26330 28 70 44 62 29 3b 0a 20 20 69 66 28 20 72 63 21  (pDb);.  if( rc!
26340 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65 74 75 72 6e  =LSM_OK ) return
26350 20 72 63 3b 0a 20 20 70 57 6f 72 6b 65 72 20 3d   rc;.  pWorker =
26360 20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 3b 0a 0a   pDb->pWorker;..
26370 20 20 2f 2a 20 49 66 20 74 68 69 73 20 63 6f 6e    /* If this con
26380 6e 65 63 74 69 6f 6e 20 69 73 20 64 6f 69 6e 67  nection is doing
26390 20 61 75 74 6f 2d 63 68 65 63 6b 70 6f 69 6e 74   auto-checkpoint
263a0 73 2c 20 73 65 74 20 6e 4d 61 78 20 28 61 6e 64  s, set nMax (and
263b0 20 6e 52 65 6d 29 20 73 6f 0a 20 20 2a 2a 20 74   nRem) so.  ** t
263c0 68 61 74 20 74 68 69 73 20 63 61 6c 6c 20 73 74  hat this call st
263d0 6f 70 73 20 77 72 69 74 69 6e 67 20 77 68 65 6e  ops writing when
263e0 20 74 68 65 20 61 75 74 6f 2d 63 68 65 63 6b 70   the auto-checkp
263f0 6f 69 6e 74 20 69 73 20 64 75 65 2e 20 54 68 65  oint is due. The
26400 0a 20 20 2a 2a 20 63 61 6c 6c 65 72 20 77 69 6c  .  ** caller wil
26410 6c 20 64 6f 20 74 68 65 20 63 68 65 63 6b 70 6f  l do the checkpo
26420 69 6e 74 2c 20 74 68 65 6e 20 70 6f 73 73 69 62  int, then possib
26430 6c 79 20 63 61 6c 6c 20 74 68 69 73 20 66 75 6e  ly call this fun
26440 63 74 69 6f 6e 20 61 67 61 69 6e 2e 20 2a 2f 0a  ction again. */.
26450 20 20 69 66 28 20 62 53 68 75 74 64 6f 77 6e 3d    if( bShutdown=
26460 3d 30 20 26 26 20 70 44 62 2d 3e 6e 41 75 74 6f  =0 && pDb->nAuto
26470 63 6b 70 74 20 29 7b 0a 20 20 20 20 75 33 32 20  ckpt ){.    u32 
26480 6e 53 79 6e 63 3b 0a 20 20 20 20 75 33 32 20 6e  nSync;.    u32 n
26490 55 6e 73 79 6e 63 3b 0a 20 20 20 20 69 6e 74 20  Unsync;.    int 
264a0 6e 50 67 73 7a 3b 0a 0a 20 20 20 20 6c 73 6d 43  nPgsz;..    lsmC
264b0 68 65 63 6b 70 6f 69 6e 74 53 79 6e 63 65 64 28  heckpointSynced(
264c0 70 44 62 2c 20 30 2c 20 30 2c 20 26 6e 53 79 6e  pDb, 0, 0, &nSyn
264d0 63 29 3b 0a 20 20 20 20 6e 55 6e 73 79 6e 63 20  c);.    nUnsync 
264e0 3d 20 6c 73 6d 43 68 65 63 6b 70 6f 69 6e 74 4e  = lsmCheckpointN
264f0 57 72 69 74 65 28 70 44 62 2d 3e 70 53 68 6d 68  Write(pDb->pShmh
26500 64 72 2d 3e 61 53 6e 61 70 31 2c 20 30 29 3b 0a  dr->aSnap1, 0);.
26510 20 20 20 20 6e 50 67 73 7a 20 3d 20 6c 73 6d 43      nPgsz = lsmC
26520 68 65 63 6b 70 6f 69 6e 74 50 67 73 7a 28 70 44  heckpointPgsz(pD
26530 62 2d 3e 70 53 68 6d 68 64 72 2d 3e 61 53 6e 61  b->pShmhdr->aSna
26540 70 31 29 3b 0a 0a 20 20 20 20 6e 4d 61 78 20 3d  p1);..    nMax =
26550 20 28 69 6e 74 29 4c 53 4d 5f 4d 49 4e 28 6e 4d   (int)LSM_MIN(nM
26560 61 78 2c 20 28 70 44 62 2d 3e 6e 41 75 74 6f 63  ax, (pDb->nAutoc
26570 6b 70 74 2f 6e 50 67 73 7a 29 20 2d 20 28 69 6e  kpt/nPgsz) - (in
26580 74 29 28 6e 55 6e 73 79 6e 63 2d 6e 53 79 6e 63  t)(nUnsync-nSync
26590 29 29 3b 0a 20 20 20 20 69 66 28 20 6e 4d 61 78  ));.    if( nMax
265a0 3c 6e 52 65 6d 20 29 7b 0a 20 20 20 20 20 20 62  <nRem ){.      b
265b0 43 6b 70 74 20 3d 20 31 3b 0a 20 20 20 20 20 20  Ckpt = 1;.      
265c0 6e 52 65 6d 20 3d 20 4c 53 4d 5f 4d 41 58 28 6e  nRem = LSM_MAX(n
265d0 4d 61 78 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 20  Max, 0);.    }. 
265e0 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 72   }..  /* If ther
265f0 65 20 65 78 69 73 74 73 20 69 6e 2d 6d 65 6d 6f  e exists in-memo
26600 72 79 20 64 61 74 61 20 72 65 61 64 79 20 74 6f  ry data ready to
26610 20 62 65 20 66 6c 75 73 68 65 64 20 74 6f 20 64   be flushed to d
26620 69 73 6b 2c 20 61 74 74 65 6d 70 74 0a 20 20 2a  isk, attempt.  *
26630 2a 20 74 6f 20 66 6c 75 73 68 20 69 74 20 6e 6f  * to flush it no
26640 77 2e 20 20 2a 2f 0a 20 20 69 66 28 20 70 44 62  w.  */.  if( pDb
26650 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 3d 3d 30 20  ->nTransOpen==0 
26660 29 7b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 54  ){.    rc = lsmT
26670 72 65 65 4c 6f 61 64 48 65 61 64 65 72 28 70 44  reeLoadHeader(pD
26680 62 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 69 66 28  b, 0);.  }.  if(
26690 20 73 6f 72 74 65 64 54 72 65 65 48 61 73 4f 6c   sortedTreeHasOl
266a0 64 28 70 44 62 2c 20 26 72 63 29 20 29 7b 0a 20  d(pDb, &rc) ){. 
266b0 20 20 20 2f 2a 20 73 6f 72 74 65 64 44 62 49 73     /* sortedDbIs
266c0 46 75 6c 6c 28 29 20 72 65 74 75 72 6e 73 20 6e  Full() returns n
266d0 6f 6e 2d 7a 65 72 6f 20 69 66 20 65 69 74 68 65  on-zero if eithe
266e0 72 20 28 61 29 20 74 68 65 72 65 20 61 72 65 20  r (a) there are 
266f0 74 6f 6f 20 6d 61 6e 79 0a 20 20 20 20 2a 2a 20  too many.    ** 
26700 6c 65 76 65 6c 73 20 69 6e 20 74 6f 74 61 6c 20  levels in total 
26710 69 6e 20 74 68 65 20 64 62 2c 20 6f 72 20 28 62  in the db, or (b
26720 29 20 74 68 65 72 65 20 61 72 65 20 74 6f 6f 20  ) there are too 
26730 6d 61 6e 79 20 6c 65 76 65 6c 73 20 77 69 74 68  many levels with
26740 20 74 68 65 0a 20 20 20 20 2a 2a 20 74 68 65 20   the.    ** the 
26750 73 61 6d 65 20 61 67 65 20 69 6e 20 74 68 65 20  same age in the 
26760 64 62 2e 20 45 69 74 68 65 72 20 77 61 79 2c 20  db. Either way, 
26770 63 61 6c 6c 20 73 6f 72 74 65 64 57 6f 72 6b 28  call sortedWork(
26780 29 20 74 6f 20 6d 65 72 67 65 20 0a 20 20 20 20  ) to merge .    
26790 2a 2a 20 65 78 69 73 74 69 6e 67 20 73 65 67 6d  ** existing segm
267a0 65 6e 74 73 20 74 6f 67 65 74 68 65 72 20 75 6e  ents together un
267b0 74 69 6c 20 74 68 69 73 20 63 6f 6e 64 69 74 69  til this conditi
267c0 6f 6e 20 69 73 20 63 6c 65 61 72 65 64 2e 20 20  on is cleared.  
267d0 2a 2f 0a 20 20 20 20 69 66 28 20 73 6f 72 74 65  */.    if( sorte
267e0 64 44 62 49 73 46 75 6c 6c 28 70 44 62 29 20 29  dDbIsFull(pDb) )
267f0 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 50 67 20  {.      int nPg 
26800 3d 20 30 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  = 0;.      rc = 
26810 73 6f 72 74 65 64 57 6f 72 6b 28 70 44 62 2c 20  sortedWork(pDb, 
26820 6e 52 65 6d 2c 20 6e 4d 65 72 67 65 2c 20 31 2c  nRem, nMerge, 1,
26830 20 26 6e 50 67 29 3b 0a 20 20 20 20 20 20 6e 52   &nPg);.      nR
26840 65 6d 20 2d 3d 20 6e 50 67 3b 0a 20 20 20 20 20  em -= nPg;.     
26850 20 61 73 73 65 72 74 28 20 72 63 21 3d 4c 53 4d   assert( rc!=LSM
26860 5f 4f 4b 20 7c 7c 20 6e 52 65 6d 3c 3d 30 20 7c  _OK || nRem<=0 |
26870 7c 20 21 73 6f 72 74 65 64 44 62 49 73 46 75 6c  | !sortedDbIsFul
26880 6c 28 70 44 62 29 20 29 3b 0a 20 20 20 20 20 20  l(pDb) );.      
26890 62 44 69 72 74 79 20 3d 20 31 3b 0a 20 20 20 20  bDirty = 1;.    
268a0 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  }..    if( rc==L
268b0 53 4d 5f 4f 4b 20 26 26 20 6e 52 65 6d 3e 30 20  SM_OK && nRem>0 
268c0 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 50 67  ){.      int nPg
268d0 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 63 20 3d   = 0;.      rc =
268e0 20 73 6f 72 74 65 64 4e 65 77 54 6f 70 6c 65 76   sortedNewToplev
268f0 65 6c 28 70 44 62 2c 20 54 52 45 45 5f 4f 4c 44  el(pDb, TREE_OLD
26900 2c 20 26 6e 50 67 29 3b 0a 20 20 20 20 20 20 6e  , &nPg);.      n
26910 52 65 6d 20 2d 3d 20 6e 50 67 3b 0a 20 20 20 20  Rem -= nPg;.    
26920 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
26930 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
26940 70 44 62 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 3e  pDb->nTransOpen>
26950 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6c  0 ){.          l
26960 73 6d 54 72 65 65 44 69 73 63 61 72 64 4f 6c 64  smTreeDiscardOld
26970 28 70 44 62 29 3b 0a 20 20 20 20 20 20 20 20 7d  (pDb);.        }
26980 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 6c 73  .        rc = ls
26990 6d 53 61 76 65 57 6f 72 6b 65 72 28 70 44 62 2c  mSaveWorker(pDb,
269a0 20 31 29 3b 0a 20 20 20 20 20 20 20 20 62 44 69   1);.        bDi
269b0 72 74 79 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d  rty = 0;.      }
269c0 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
269d0 20 49 66 20 6e 50 61 67 65 20 69 73 20 73 74 69   If nPage is sti
269e0 6c 6c 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  ll greater than 
269f0 7a 65 72 6f 2c 20 64 6f 20 73 6f 6d 65 20 6d 65  zero, do some me
26a00 72 67 69 6e 67 2e 20 2a 2f 0a 20 20 69 66 28 20  rging. */.  if( 
26a10 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 6e 52  rc==LSM_OK && nR
26a20 65 6d 3e 30 20 26 26 20 62 53 68 75 74 64 6f 77  em>0 && bShutdow
26a30 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20  n==0 ){.    int 
26a40 6e 50 67 20 3d 20 30 3b 0a 20 20 20 20 72 63 20  nPg = 0;.    rc 
26a50 3d 20 73 6f 72 74 65 64 57 6f 72 6b 28 70 44 62  = sortedWork(pDb
26a60 2c 20 6e 52 65 6d 2c 20 6e 4d 65 72 67 65 2c 20  , nRem, nMerge, 
26a70 30 2c 20 26 6e 50 67 29 3b 0a 20 20 20 20 6e 52  0, &nPg);.    nR
26a80 65 6d 20 2d 3d 20 6e 50 67 3b 0a 20 20 20 20 69  em -= nPg;.    i
26a90 66 28 20 6e 50 67 20 29 20 62 44 69 72 74 79 20  f( nPg ) bDirty 
26aa0 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49  = 1;.  }..  /* I
26ab0 66 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  f the in-memory 
26ac0 70 61 72 74 20 6f 66 20 74 68 65 20 66 72 65 65  part of the free
26ad0 2d 6c 69 73 74 20 69 73 20 74 6f 6f 20 6c 61 72  -list is too lar
26ae0 67 65 2c 20 77 72 69 74 65 20 61 20 6e 65 77 20  ge, write a new 
26af0 0a 20 20 2a 2a 20 74 6f 70 2d 6c 65 76 65 6c 20  .  ** top-level 
26b00 63 6f 6e 74 61 69 6e 69 6e 67 20 6a 75 73 74 20  containing just 
26b10 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20 66 72  the in-memory fr
26b20 65 65 2d 6c 69 73 74 20 65 6e 74 72 69 65 73 20  ee-list entries 
26b30 74 6f 20 64 69 73 6b 2e 20 2a 2f 0a 20 20 69 66  to disk. */.  if
26b40 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20  ( rc==LSM_OK && 
26b50 70 44 62 2d 3e 70 57 6f 72 6b 65 72 2d 3e 66 72  pDb->pWorker->fr
26b60 65 65 6c 69 73 74 2e 6e 45 6e 74 72 79 20 3e 20  eelist.nEntry > 
26b70 70 44 62 2d 3e 6e 4d 61 78 46 72 65 65 6c 69 73  pDb->nMaxFreelis
26b80 74 20 29 7b 0a 20 20 20 20 77 68 69 6c 65 28 20  t ){.    while( 
26b90 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 6c 73  rc==LSM_OK && ls
26ba0 6d 44 61 74 61 62 61 73 65 46 75 6c 6c 28 70 44  mDatabaseFull(pD
26bb0 62 29 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  b) ){.      int 
26bc0 6e 50 67 20 3d 20 30 3b 0a 20 20 20 20 20 20 72  nPg = 0;.      r
26bd0 63 20 3d 20 73 6f 72 74 65 64 57 6f 72 6b 28 70  c = sortedWork(p
26be0 44 62 2c 20 31 36 2c 20 6e 4d 65 72 67 65 2c 20  Db, 16, nMerge, 
26bf0 31 2c 20 26 6e 50 67 29 3b 0a 20 20 20 20 20 20  1, &nPg);.      
26c00 6e 52 65 6d 20 2d 3d 20 6e 50 67 3b 0a 20 20 20  nRem -= nPg;.   
26c10 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c   }.    if( rc==L
26c20 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  SM_OK ){.      r
26c30 63 20 3d 20 73 6f 72 74 65 64 4e 65 77 46 72 65  c = sortedNewFre
26c40 65 6c 69 73 74 4f 6e 6c 79 28 70 44 62 29 3b 0a  elistOnly(pDb);.
26c50 20 20 20 20 7d 0a 20 20 20 20 62 44 69 72 74 79      }.    bDirty
26c60 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 69 66 28   = 1;.  }..  if(
26c70 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20   rc==LSM_OK ){. 
26c80 20 20 20 2a 70 6e 57 72 69 74 65 20 3d 20 28 6e     *pnWrite = (n
26c90 4d 61 78 20 2d 20 6e 52 65 6d 29 3b 0a 20 20 20  Max - nRem);.   
26ca0 20 2a 70 62 43 6b 70 74 20 3d 20 28 62 43 6b 70   *pbCkpt = (bCkp
26cb0 74 20 26 26 20 6e 52 65 6d 3c 3d 30 29 3b 0a 20  t && nRem<=0);. 
26cc0 20 20 20 69 66 28 20 6e 4d 65 72 67 65 3d 3d 31     if( nMerge==1
26cd0 20 26 26 20 70 44 62 2d 3e 6e 41 75 74 6f 63 6b   && pDb->nAutock
26ce0 70 74 3e 30 20 26 26 20 2a 70 6e 57 72 69 74 65  pt>0 && *pnWrite
26cf0 3e 30 0a 20 20 20 20 20 26 26 20 70 57 6f 72 6b  >0.     && pWork
26d00 65 72 2d 3e 70 4c 65 76 65 6c 20 0a 20 20 20 20  er->pLevel .    
26d10 20 26 26 20 70 57 6f 72 6b 65 72 2d 3e 70 4c 65   && pWorker->pLe
26d20 76 65 6c 2d 3e 6e 52 69 67 68 74 3d 3d 30 20 0a  vel->nRight==0 .
26d30 20 20 20 20 20 26 26 20 70 57 6f 72 6b 65 72 2d       && pWorker-
26d40 3e 70 4c 65 76 65 6c 2d 3e 70 4e 65 78 74 3d 3d  >pLevel->pNext==
26d50 30 20 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20  0 .    ){.      
26d60 2a 70 62 43 6b 70 74 20 3d 20 31 3b 0a 20 20 20  *pbCkpt = 1;.   
26d70 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63   }.  }..  if( rc
26d80 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 62 44 69 72  ==LSM_OK && bDir
26d90 74 79 20 29 7b 0a 20 20 20 20 6c 73 6d 46 69 6e  ty ){.    lsmFin
26da0 69 73 68 57 6f 72 6b 28 70 44 62 2c 20 30 2c 20  ishWork(pDb, 0, 
26db0 26 72 63 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  &rc);.  }else{. 
26dc0 20 20 20 69 6e 74 20 72 63 64 75 6d 6d 79 20 3d     int rcdummy =
26dd0 20 4c 53 4d 5f 42 55 53 59 3b 0a 20 20 20 20 6c   LSM_BUSY;.    l
26de0 73 6d 46 69 6e 69 73 68 57 6f 72 6b 28 70 44 62  smFinishWork(pDb
26df0 2c 20 30 2c 20 26 72 63 64 75 6d 6d 79 29 3b 0a  , 0, &rcdummy);.
26e00 20 20 20 20 2a 70 6e 57 72 69 74 65 20 3d 20 30      *pnWrite = 0
26e10 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20  ;.  }.  assert( 
26e20 70 44 62 2d 3e 70 57 6f 72 6b 65 72 3d 3d 30 20  pDb->pWorker==0 
26e30 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
26e40 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 64 6f  }..static int do
26e50 4c 73 6d 57 6f 72 6b 28 6c 73 6d 5f 64 62 20 2a  LsmWork(lsm_db *
26e60 70 44 62 2c 20 69 6e 74 20 6e 4d 65 72 67 65 2c  pDb, int nMerge,
26e70 20 69 6e 74 20 6e 50 61 67 65 2c 20 69 6e 74 20   int nPage, int 
26e80 2a 70 6e 57 72 69 74 65 29 7b 0a 20 20 69 6e 74  *pnWrite){.  int
26e90 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20   rc = LSM_OK;   
26ea0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
26eb0 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
26ec0 20 69 6e 74 20 6e 57 72 69 74 65 20 3d 20 30 3b   int nWrite = 0;
26ed0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26ee0 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 61   /* Number of pa
26ef0 67 65 73 20 77 72 69 74 74 65 6e 20 2a 2f 0a 0a  ges written */..
26f00 20 20 61 73 73 65 72 74 28 20 6e 4d 65 72 67 65    assert( nMerge
26f10 3e 3d 31 20 29 3b 0a 0a 20 20 69 66 28 20 6e 50  >=1 );..  if( nP
26f20 61 67 65 21 3d 30 20 29 7b 0a 20 20 20 20 69 6e  age!=0 ){.    in
26f30 74 20 62 43 6b 70 74 20 3d 20 30 3b 0a 20 20 20  t bCkpt = 0;.   
26f40 20 64 6f 20 7b 0a 20 20 20 20 20 20 69 6e 74 20   do {.      int 
26f50 6e 54 68 69 73 20 3d 20 30 3b 0a 20 20 20 20 20  nThis = 0;.     
26f60 20 69 6e 74 20 6e 52 65 71 20 3d 20 28 6e 50 61   int nReq = (nPa
26f70 67 65 3e 3d 30 29 20 3f 20 28 6e 50 61 67 65 2d  ge>=0) ? (nPage-
26f80 6e 57 72 69 74 65 29 20 3a 20 28 28 69 6e 74 29  nWrite) : ((int)
26f90 30 78 37 46 46 46 46 46 46 46 29 3b 0a 0a 20 20  0x7FFFFFFF);..  
26fa0 20 20 20 20 62 43 6b 70 74 20 3d 20 30 3b 0a 20      bCkpt = 0;. 
26fb0 20 20 20 20 20 72 63 20 3d 20 64 6f 4c 73 6d 53       rc = doLsmS
26fc0 69 6e 67 6c 65 57 6f 72 6b 28 70 44 62 2c 20 30  ingleWork(pDb, 0
26fd0 2c 20 6e 4d 65 72 67 65 2c 20 6e 52 65 71 2c 20  , nMerge, nReq, 
26fe0 26 6e 54 68 69 73 2c 20 26 62 43 6b 70 74 29 3b  &nThis, &bCkpt);
26ff0 0a 20 20 20 20 20 20 6e 57 72 69 74 65 20 2b 3d  .      nWrite +=
27000 20 6e 54 68 69 73 3b 0a 20 20 20 20 20 20 69 66   nThis;.      if
27010 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20  ( rc==LSM_OK && 
27020 62 43 6b 70 74 20 29 7b 0a 20 20 20 20 20 20 20  bCkpt ){.       
27030 20 72 63 20 3d 20 6c 73 6d 5f 63 68 65 63 6b 70   rc = lsm_checkp
27040 6f 69 6e 74 28 70 44 62 2c 20 30 29 3b 0a 20 20  oint(pDb, 0);.  
27050 20 20 20 20 7d 0a 20 20 20 20 7d 77 68 69 6c 65      }.    }while
27060 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20  ( rc==LSM_OK && 
27070 62 43 6b 70 74 20 26 26 20 28 6e 57 72 69 74 65  bCkpt && (nWrite
27080 3c 6e 50 61 67 65 20 7c 7c 20 6e 50 61 67 65 3c  <nPage || nPage<
27090 30 29 20 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  0) );.  }..  if(
270a0 20 70 6e 57 72 69 74 65 20 29 7b 0a 20 20 20 20   pnWrite ){.    
270b0 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
270c0 7b 0a 20 20 20 20 20 20 2a 70 6e 57 72 69 74 65  {.      *pnWrite
270d0 20 3d 20 6e 57 72 69 74 65 3b 0a 20 20 20 20 7d   = nWrite;.    }
270e0 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a 70 6e 57  else{.      *pnW
270f0 72 69 74 65 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  rite = 0;.    }.
27100 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
27110 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 65 72 66 6f 72  .}../*.** Perfor
27120 6d 20 77 6f 72 6b 20 74 6f 20 6d 65 72 67 65 20  m work to merge 
27130 64 61 74 61 62 61 73 65 20 73 65 67 6d 65 6e 74  database segment
27140 73 20 74 6f 67 65 74 68 65 72 2e 0a 2a 2f 0a 69  s together..*/.i
27150 6e 74 20 6c 73 6d 5f 77 6f 72 6b 28 6c 73 6d 5f  nt lsm_work(lsm_
27160 64 62 20 2a 70 44 62 2c 20 69 6e 74 20 6e 4d 65  db *pDb, int nMe
27170 72 67 65 2c 20 69 6e 74 20 6e 4b 42 2c 20 69 6e  rge, int nKB, in
27180 74 20 2a 70 6e 57 72 69 74 65 29 7b 0a 20 20 69  t *pnWrite){.  i
27190 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
271a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
271b0 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
271c0 0a 20 20 69 6e 74 20 6e 50 67 73 7a 3b 20 20 20  .  int nPgsz;   
271d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
271e0 20 20 20 2f 2a 20 4e 6f 6d 69 6e 61 6c 20 70 61     /* Nominal pa
271f0 67 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73  ge size in bytes
27200 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 61 67 65 3b   */.  int nPage;
27210 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27220 20 20 20 20 20 20 2f 2a 20 45 71 75 69 76 61 6c        /* Equival
27230 65 6e 74 20 6f 66 20 6e 4b 42 20 69 6e 20 70 61  ent of nKB in pa
27240 67 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 57 72  ges */.  int nWr
27250 69 74 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20  ite = 0;        
27260 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
27270 65 72 20 6f 66 20 70 61 67 65 73 20 77 72 69 74  er of pages writ
27280 74 65 6e 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 69  ten */..  /* Thi
27290 73 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 6e  s function may n
272a0 6f 74 20 62 65 20 63 61 6c 6c 65 64 20 69 66 20  ot be called if 
272b0 70 44 62 20 68 61 73 20 61 6e 20 6f 70 65 6e 20  pDb has an open 
272c0 72 65 61 64 20 6f 72 20 77 72 69 74 65 0a 20 20  read or write.  
272d0 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20  ** transaction. 
272e0 52 65 74 75 72 6e 20 4c 53 4d 5f 4d 49 53 55 53  Return LSM_MISUS
272f0 45 20 69 66 20 61 6e 20 61 70 70 6c 69 63 61 74  E if an applicat
27300 69 6f 6e 20 61 74 74 65 6d 70 74 73 20 74 68 69  ion attempts thi
27310 73 2e 20 20 2a 2f 0a 20 20 69 66 28 20 70 44 62  s.  */.  if( pDb
27320 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 20 7c 7c 20  ->nTransOpen || 
27330 70 44 62 2d 3e 70 43 73 72 20 29 20 72 65 74 75  pDb->pCsr ) retu
27340 72 6e 20 4c 53 4d 5f 4d 49 53 55 53 45 5f 42 4b  rn LSM_MISUSE_BK
27350 50 54 3b 0a 20 20 69 66 28 20 6e 4d 65 72 67 65  PT;.  if( nMerge
27360 3c 3d 30 20 29 20 6e 4d 65 72 67 65 20 3d 20 70  <=0 ) nMerge = p
27370 44 62 2d 3e 6e 4d 65 72 67 65 3b 0a 0a 20 20 6c  Db->nMerge;..  l
27380 73 6d 46 73 50 75 72 67 65 43 61 63 68 65 28 70  smFsPurgeCache(p
27390 44 62 2d 3e 70 46 53 29 3b 0a 0a 20 20 2f 2a 20  Db->pFS);..  /* 
273a0 43 6f 6e 76 65 72 74 20 66 72 6f 6d 20 4b 42 20  Convert from KB 
273b0 74 6f 20 70 61 67 65 73 20 2a 2f 0a 20 20 6e 50  to pages */.  nP
273c0 67 73 7a 20 3d 20 6c 73 6d 46 73 50 61 67 65 53  gsz = lsmFsPageS
273d0 69 7a 65 28 70 44 62 2d 3e 70 46 53 29 3b 0a 20  ize(pDb->pFS);. 
273e0 20 69 66 28 20 6e 4b 42 3e 3d 30 20 29 7b 0a 20   if( nKB>=0 ){. 
273f0 20 20 20 6e 50 61 67 65 20 3d 20 28 28 69 36 34     nPage = ((i64
27400 29 6e 4b 42 20 2a 20 31 30 32 34 20 2b 20 6e 50  )nKB * 1024 + nP
27410 67 73 7a 20 2d 20 31 29 20 2f 20 6e 50 67 73 7a  gsz - 1) / nPgsz
27420 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 6e  ;.  }else{.    n
27430 50 61 67 65 20 3d 20 2d 31 3b 0a 20 20 7d 0a 0a  Page = -1;.  }..
27440 20 20 72 63 20 3d 20 64 6f 4c 73 6d 57 6f 72 6b    rc = doLsmWork
27450 28 70 44 62 2c 20 6e 4d 65 72 67 65 2c 20 6e 50  (pDb, nMerge, nP
27460 61 67 65 2c 20 26 6e 57 72 69 74 65 29 3b 0a 20  age, &nWrite);. 
27470 20 0a 20 20 69 66 28 20 70 6e 57 72 69 74 65 20   .  if( pnWrite 
27480 29 7b 0a 20 20 20 20 2f 2a 20 43 6f 6e 76 65 72  ){.    /* Conver
27490 74 20 62 61 63 6b 20 66 72 6f 6d 20 70 61 67 65  t back from page
274a0 73 20 74 6f 20 4b 42 20 2a 2f 0a 20 20 20 20 2a  s to KB */.    *
274b0 70 6e 57 72 69 74 65 20 3d 20 28 69 6e 74 29 28  pnWrite = (int)(
274c0 28 28 69 36 34 29 6e 57 72 69 74 65 20 2a 20 31  ((i64)nWrite * 1
274d0 30 32 34 20 2b 20 6e 50 67 73 7a 20 2d 20 31 29  024 + nPgsz - 1)
274e0 20 2f 20 6e 50 67 73 7a 29 3b 0a 20 20 7d 0a 20   / nPgsz);.  }. 
274f0 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69   return rc;.}..i
27500 6e 74 20 6c 73 6d 5f 66 6c 75 73 68 28 6c 73 6d  nt lsm_flush(lsm
27510 5f 64 62 20 2a 64 62 29 7b 0a 20 20 69 6e 74 20  _db *db){.  int 
27520 72 63 3b 0a 0a 20 20 69 66 28 20 64 62 2d 3e 6e  rc;..  if( db->n
27530 54 72 61 6e 73 4f 70 65 6e 3e 30 20 7c 7c 20 64  TransOpen>0 || d
27540 62 2d 3e 70 43 73 72 20 29 7b 0a 20 20 20 20 72  b->pCsr ){.    r
27550 63 20 3d 20 4c 53 4d 5f 4d 49 53 55 53 45 5f 42  c = LSM_MISUSE_B
27560 4b 50 54 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  KPT;.  }else{.  
27570 20 20 72 63 20 3d 20 6c 73 6d 42 65 67 69 6e 57    rc = lsmBeginW
27580 72 69 74 65 54 72 61 6e 73 28 64 62 29 3b 0a 20  riteTrans(db);. 
27590 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f     if( rc==LSM_O
275a0 4b 20 29 7b 0a 20 20 20 20 20 20 6c 73 6d 46 6c  K ){.      lsmFl
275b0 75 73 68 54 72 65 65 54 6f 44 69 73 6b 28 64 62  ushTreeToDisk(db
275c0 29 3b 0a 20 20 20 20 20 20 6c 73 6d 54 72 65 65  );.      lsmTree
275d0 44 69 73 63 61 72 64 4f 6c 64 28 64 62 29 3b 0a  DiscardOld(db);.
275e0 20 20 20 20 20 20 6c 73 6d 54 72 65 65 4d 61 6b        lsmTreeMak
275f0 65 4f 6c 64 28 64 62 29 3b 0a 20 20 20 20 20 20  eOld(db);.      
27600 6c 73 6d 54 72 65 65 44 69 73 63 61 72 64 4f 6c  lsmTreeDiscardOl
27610 64 28 64 62 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  d(db);.    }..  
27620 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
27630 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 6c   ){.      rc = l
27640 73 6d 46 69 6e 69 73 68 57 72 69 74 65 54 72 61  smFinishWriteTra
27650 6e 73 28 64 62 2c 20 31 29 3b 0a 20 20 20 20 7d  ns(db, 1);.    }
27660 65 6c 73 65 7b 0a 20 20 20 20 20 20 6c 73 6d 46  else{.      lsmF
27670 69 6e 69 73 68 57 72 69 74 65 54 72 61 6e 73 28  inishWriteTrans(
27680 64 62 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 20 20  db, 0);.    }.  
27690 20 20 6c 73 6d 46 69 6e 69 73 68 52 65 61 64 54    lsmFinishReadT
276a0 72 61 6e 73 28 64 62 29 3b 0a 20 20 7d 0a 0a 20  rans(db);.  }.. 
276b0 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
276c0 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
276d0 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 69 6e 20  on is called in 
276e0 61 75 74 6f 2d 77 6f 72 6b 20 6d 6f 64 65 20 74  auto-work mode t
276f0 6f 20 70 65 72 66 6f 72 6d 20 6d 65 72 67 69 6e  o perform mergin
27700 67 20 77 6f 72 6b 20 6f 6e 0a 2a 2a 20 74 68 65  g work on.** the
27710 20 64 61 74 61 20 73 74 72 75 63 74 75 72 65 2e   data structure.
27720 20 49 74 20 70 65 72 66 6f 72 6d 73 20 65 6e 6f   It performs eno
27730 75 67 68 20 6d 65 72 67 69 6e 67 20 77 6f 72 6b  ugh merging work
27740 20 74 6f 20 70 72 65 76 65 6e 74 20 74 68 65 0a   to prevent the.
27750 2a 2a 20 68 65 69 67 68 74 20 6f 66 20 74 68 65  ** height of the
27760 20 74 72 65 65 20 66 72 6f 6d 20 67 72 6f 77 69   tree from growi
27770 6e 67 20 69 6e 64 65 66 69 6e 69 74 65 6c 79 20  ng indefinitely 
27780 61 73 73 75 6d 69 6e 67 20 74 68 61 74 20 72 6f  assuming that ro
27790 75 67 68 6c 79 0a 2a 2a 20 6e 55 6e 69 74 20 64  ughly.** nUnit d
277a0 61 74 61 62 61 73 65 20 70 61 67 65 73 20 77 6f  atabase pages wo
277b0 72 74 68 20 6f 66 20 64 61 74 61 20 68 61 76 65  rth of data have
277c0 20 62 65 65 6e 20 77 72 69 74 74 65 6e 20 74 6f   been written to
277d0 20 74 68 65 20 64 61 74 61 62 61 73 65 0a 2a 2a   the database.**
277e0 20 28 69 2e 65 2e 20 74 68 65 20 69 6e 2d 6d 65   (i.e. the in-me
277f0 6d 6f 72 79 20 74 72 65 65 29 20 73 69 6e 63 65  mory tree) since
27800 20 74 68 65 20 6c 61 73 74 20 63 61 6c 6c 2e 0a   the last call..
27810 2a 2f 0a 69 6e 74 20 6c 73 6d 53 6f 72 74 65 64  */.int lsmSorted
27820 41 75 74 6f 57 6f 72 6b 28 0a 20 20 6c 73 6d 5f  AutoWork(.  lsm_
27830 64 62 20 2a 70 44 62 2c 20 20 20 20 20 20 20 20  db *pDb,        
27840 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
27850 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a  atabase handle *
27860 2f 0a 20 20 69 6e 74 20 6e 55 6e 69 74 20 20 20  /.  int nUnit   
27870 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27880 20 20 20 20 2f 2a 20 50 61 67 65 73 20 6f 66 20      /* Pages of 
27890 64 61 74 61 20 77 72 69 74 74 65 6e 20 74 6f 20  data written to 
278a0 69 6e 2d 6d 65 6d 6f 72 79 20 74 72 65 65 20 2a  in-memory tree *
278b0 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  /.){.  int rc = 
278c0 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  LSM_OK;         
278d0 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
278e0 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 6e   code */.  int n
278f0 44 65 70 74 68 20 3d 20 30 3b 20 20 20 20 20 20  Depth = 0;      
27900 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
27910 72 72 65 6e 74 20 68 65 69 67 68 74 20 6f 66 20  rrent height of 
27920 74 72 65 65 20 28 6c 6f 6e 67 65 73 74 20 70 61  tree (longest pa
27930 74 68 29 20 2a 2f 0a 20 20 4c 65 76 65 6c 20 2a  th) */.  Level *
27940 70 4c 65 76 65 6c 3b 20 20 20 20 20 20 20 20 20  pLevel;         
27950 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64           /* Used
27960 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
27970 75 67 68 20 6c 65 76 65 6c 73 20 2a 2f 0a 20 20  ugh levels */.  
27980 69 6e 74 20 62 52 65 73 74 6f 72 65 20 3d 20 30  int bRestore = 0
27990 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 44 62  ;..  assert( pDb
279a0 2d 3e 70 57 6f 72 6b 65 72 3d 3d 30 20 29 3b 0a  ->pWorker==0 );.
279b0 20 20 61 73 73 65 72 74 28 20 70 44 62 2d 3e 6e    assert( pDb->n
279c0 54 72 61 6e 73 4f 70 65 6e 3e 30 20 29 3b 0a 0a  TransOpen>0 );..
279d0 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20 68    /* Determine h
279e0 6f 77 20 6d 61 6e 79 20 75 6e 69 74 73 20 6f 66  ow many units of
279f0 20 77 6f 72 6b 20 74 6f 20 64 6f 20 62 65 66 6f   work to do befo
27a00 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 20 4f 6e  re returning. On
27a10 65 20 75 6e 69 74 20 6f 66 0a 20 20 2a 2a 20 77  e unit of.  ** w
27a20 6f 72 6b 20 69 73 20 61 63 68 69 65 76 65 64 20  ork is achieved 
27a30 62 79 20 77 72 69 74 69 6e 67 20 6f 6e 65 20 70  by writing one p
27a40 61 67 65 20 28 7e 34 4b 42 29 20 6f 66 20 6d 65  age (~4KB) of me
27a50 72 67 65 64 20 64 61 74 61 2e 20 20 2a 2f 0a 20  rged data.  */. 
27a60 20 66 6f 72 28 70 4c 65 76 65 6c 3d 6c 73 6d 44   for(pLevel=lsmD
27a70 62 53 6e 61 70 73 68 6f 74 4c 65 76 65 6c 28 70  bSnapshotLevel(p
27a80 44 62 2d 3e 70 43 6c 69 65 6e 74 29 3b 20 70 4c  Db->pClient); pL
27a90 65 76 65 6c 3b 20 70 4c 65 76 65 6c 3d 70 4c 65  evel; pLevel=pLe
27aa0 76 65 6c 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  vel->pNext){.   
27ab0 20 2f 2a 20 6e 44 65 70 74 68 20 2b 3d 20 4c 53   /* nDepth += LS
27ac0 4d 5f 4d 41 58 28 31 2c 20 70 4c 65 76 65 6c 2d  M_MAX(1, pLevel-
27ad0 3e 6e 52 69 67 68 74 29 3b 20 2a 2f 0a 20 20 20  >nRight); */.   
27ae0 20 6e 44 65 70 74 68 20 2b 3d 20 31 3b 0a 20 20   nDepth += 1;.  
27af0 7d 0a 20 20 69 66 28 20 6c 73 6d 54 72 65 65 48  }.  if( lsmTreeH
27b00 61 73 4f 6c 64 28 70 44 62 29 20 29 7b 0a 20 20  asOld(pDb) ){.  
27b10 20 20 6e 44 65 70 74 68 20 2b 3d 20 31 3b 0a 20    nDepth += 1;. 
27b20 20 20 20 62 52 65 73 74 6f 72 65 20 3d 20 31 3b     bRestore = 1;
27b30 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 53 61 76  .    rc = lsmSav
27b40 65 43 75 72 73 6f 72 73 28 70 44 62 29 3b 0a 20  eCursors(pDb);. 
27b50 20 20 20 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f     if( rc!=LSM_O
27b60 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
27b70 20 7d 0a 0a 20 20 69 66 28 20 6e 44 65 70 74 68   }..  if( nDepth
27b80 3e 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 52  >0 ){.    int nR
27b90 65 6d 61 69 6e 69 6e 67 3b 20 20 20 20 20 20 20  emaining;       
27ba0 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 69 74 73          /* Units
27bb0 20 6f 66 20 77 6f 72 6b 20 74 6f 20 64 6f 20 62   of work to do b
27bc0 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 20  efore returning 
27bd0 2a 2f 0a 0a 20 20 20 20 6e 52 65 6d 61 69 6e 69  */..    nRemaini
27be0 6e 67 20 3d 20 6e 55 6e 69 74 20 2a 20 6e 44 65  ng = nUnit * nDe
27bf0 70 74 68 3b 0a 23 69 66 64 65 66 20 4c 53 4d 5f  pth;.#ifdef LSM_
27c00 4c 4f 47 5f 57 4f 52 4b 0a 20 20 20 20 6c 73 6d  LOG_WORK.    lsm
27c10 4c 6f 67 4d 65 73 73 61 67 65 28 70 44 62 2c 20  LogMessage(pDb, 
27c20 72 63 2c 20 22 6c 73 6d 53 6f 72 74 65 64 41 75  rc, "lsmSortedAu
27c30 74 6f 57 6f 72 6b 28 29 3a 20 25 64 2a 25 64 20  toWork(): %d*%d 
27c40 3d 20 25 64 20 70 61 67 65 73 22 2c 20 0a 20 20  = %d pages", .  
27c50 20 20 20 20 20 20 6e 55 6e 69 74 2c 20 6e 44 65        nUnit, nDe
27c60 70 74 68 2c 20 6e 52 65 6d 61 69 6e 69 6e 67 29  pth, nRemaining)
27c70 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 61 73 73  ;.#endif.    ass
27c80 65 72 74 28 20 6e 52 65 6d 61 69 6e 69 6e 67 3e  ert( nRemaining>
27c90 3d 30 20 29 3b 0a 20 20 20 20 72 63 20 3d 20 64  =0 );.    rc = d
27ca0 6f 4c 73 6d 57 6f 72 6b 28 70 44 62 2c 20 70 44  oLsmWork(pDb, pD
27cb0 62 2d 3e 6e 4d 65 72 67 65 2c 20 6e 52 65 6d 61  b->nMerge, nRema
27cc0 69 6e 69 6e 67 2c 20 30 29 3b 0a 20 20 20 20 69  ining, 0);.    i
27cd0 66 28 20 72 63 3d 3d 4c 53 4d 5f 42 55 53 59 20  f( rc==LSM_BUSY 
27ce0 29 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 0a  ) rc = LSM_OK;..
27cf0 20 20 20 20 69 66 28 20 62 52 65 73 74 6f 72 65      if( bRestore
27d00 20 26 26 20 70 44 62 2d 3e 70 43 73 72 20 29 7b   && pDb->pCsr ){
27d10 0a 20 20 20 20 20 20 6c 73 6d 4d 43 75 72 73 6f  .      lsmMCurso
27d20 72 46 72 65 65 43 61 63 68 65 28 70 44 62 29 3b  rFreeCache(pDb);
27d30 0a 20 20 20 20 20 20 6c 73 6d 46 72 65 65 53 6e  .      lsmFreeSn
27d40 61 70 73 68 6f 74 28 70 44 62 2d 3e 70 45 6e 76  apshot(pDb->pEnv
27d50 2c 20 70 44 62 2d 3e 70 43 6c 69 65 6e 74 29 3b  , pDb->pClient);
27d60 0a 20 20 20 20 20 20 70 44 62 2d 3e 70 43 6c 69  .      pDb->pCli
27d70 65 6e 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 69  ent = 0;.      i
27d80 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b  f( rc==LSM_OK ){
27d90 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 6c 73  .        rc = ls
27da0 6d 43 68 65 63 6b 70 6f 69 6e 74 4c 6f 61 64 28  mCheckpointLoad(
27db0 70 44 62 2c 20 30 29 3b 0a 20 20 20 20 20 20 7d  pDb, 0);.      }
27dc0 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  .      if( rc==L
27dd0 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  SM_OK ){.       
27de0 20 72 63 20 3d 20 6c 73 6d 43 68 65 63 6b 70 6f   rc = lsmCheckpo
27df0 69 6e 74 44 65 73 65 72 69 61 6c 69 7a 65 28 70  intDeserialize(p
27e00 44 62 2c 20 30 2c 20 70 44 62 2d 3e 61 53 6e 61  Db, 0, pDb->aSna
27e10 70 73 68 6f 74 2c 20 26 70 44 62 2d 3e 70 43 6c  pshot, &pDb->pCl
27e20 69 65 6e 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20  ient);.      }. 
27e30 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d       if( rc==LSM
27e40 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72  _OK ){.        r
27e50 63 20 3d 20 6c 73 6d 52 65 73 74 6f 72 65 43 75  c = lsmRestoreCu
27e60 72 73 6f 72 73 28 70 44 62 29 3b 0a 20 20 20 20  rsors(pDb);.    
27e70 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20    }.    }.  }.. 
27e80 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
27e90 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
27ea0 6f 6e 20 69 73 20 6f 6e 6c 79 20 63 61 6c 6c 65  on is only calle
27eb0 64 20 64 75 72 69 6e 67 20 73 79 73 74 65 6d 20  d during system 
27ec0 73 68 75 74 64 6f 77 6e 2e 20 54 68 65 20 63 6f  shutdown. The co
27ed0 6e 74 65 6e 74 73 20 6f 66 0a 2a 2a 20 61 6e 79  ntents of.** any
27ee0 20 69 6e 2d 6d 65 6d 6f 72 79 20 74 72 65 65 73   in-memory trees
27ef0 20 70 72 65 73 65 6e 74 20 28 6f 6c 64 20 6f 72   present (old or
27f00 20 63 75 72 72 65 6e 74 29 20 61 72 65 20 77 72   current) are wr
27f10 69 74 74 65 6e 20 6f 75 74 20 74 6f 20 64 69 73  itten out to dis
27f20 6b 2e 0a 2a 2f 0a 69 6e 74 20 6c 73 6d 46 6c 75  k..*/.int lsmFlu
27f30 73 68 54 72 65 65 54 6f 44 69 73 6b 28 6c 73 6d  shTreeToDisk(lsm
27f40 5f 64 62 20 2a 70 44 62 29 7b 0a 20 20 69 6e 74  _db *pDb){.  int
27f50 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 6c 73 6d   rc;..  rc = lsm
27f60 42 65 67 69 6e 57 6f 72 6b 28 70 44 62 29 3b 0a  BeginWork(pDb);.
27f70 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d    while( rc==LSM
27f80 5f 4f 4b 20 26 26 20 73 6f 72 74 65 64 44 62 49  _OK && sortedDbI
27f90 73 46 75 6c 6c 28 70 44 62 29 20 29 7b 0a 20 20  sFull(pDb) ){.  
27fa0 20 20 72 63 20 3d 20 73 6f 72 74 65 64 57 6f 72    rc = sortedWor
27fb0 6b 28 70 44 62 2c 20 32 35 36 2c 20 70 44 62 2d  k(pDb, 256, pDb-
27fc0 3e 6e 4d 65 72 67 65 2c 20 31 2c 20 30 29 3b 0a  >nMerge, 1, 0);.
27fd0 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c    }..  if( rc==L
27fe0 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  SM_OK ){.    rc 
27ff0 3d 20 73 6f 72 74 65 64 4e 65 77 54 6f 70 6c 65  = sortedNewTople
28000 76 65 6c 28 70 44 62 2c 20 54 52 45 45 5f 42 4f  vel(pDb, TREE_BO
28010 54 48 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 6c  TH, 0);.  }..  l
28020 73 6d 46 69 6e 69 73 68 57 6f 72 6b 28 70 44 62  smFinishWork(pDb
28030 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 72 65 74  , 1, &rc);.  ret
28040 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
28050 20 52 65 74 75 72 6e 20 61 20 73 74 72 69 6e 67   Return a string
28060 20 72 65 70 72 65 73 65 6e 74 61 74 69 6f 6e 20   representation 
28070 6f 66 20 74 68 65 20 73 65 67 6d 65 6e 74 20 70  of the segment p
28080 61 73 73 65 64 20 61 73 20 74 68 65 20 6f 6e 6c  assed as the onl
28090 79 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 20 53  y argument..** S
280a0 70 61 63 65 20 66 6f 72 20 74 68 65 20 72 65 74  pace for the ret
280b0 75 72 6e 65 64 20 73 74 72 69 6e 67 20 69 73 20  urned string is 
280c0 61 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e 67 20  allocated using 
280d0 6c 73 6d 4d 61 6c 6c 6f 63 28 29 2c 20 61 6e 64  lsmMalloc(), and
280e0 20 73 68 6f 75 6c 64 0a 2a 2a 20 62 65 20 66 72   should.** be fr
280f0 65 65 64 20 62 79 20 74 68 65 20 63 61 6c 6c 65  eed by the calle
28100 72 20 75 73 69 6e 67 20 6c 73 6d 46 72 65 65 28  r using lsmFree(
28110 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61  )..*/.static cha
28120 72 20 2a 73 65 67 54 6f 53 74 72 69 6e 67 28 6c  r *segToString(l
28130 73 6d 5f 65 6e 76 20 2a 70 45 6e 76 2c 20 53 65  sm_env *pEnv, Se
28140 67 6d 65 6e 74 20 2a 70 53 65 67 2c 20 69 6e 74  gment *pSeg, int
28150 20 6e 4d 69 6e 29 7b 0a 20 20 69 6e 74 20 6e 53   nMin){.  int nS
28160 69 7a 65 20 3d 20 70 53 65 67 2d 3e 6e 53 69 7a  ize = pSeg->nSiz
28170 65 3b 0a 20 20 4c 73 6d 50 67 6e 6f 20 69 52 6f  e;.  LsmPgno iRo
28180 6f 74 20 3d 20 70 53 65 67 2d 3e 69 52 6f 6f 74  ot = pSeg->iRoot
28190 3b 0a 20 20 4c 73 6d 50 67 6e 6f 20 69 46 69 72  ;.  LsmPgno iFir
281a0 73 74 20 3d 20 70 53 65 67 2d 3e 69 46 69 72 73  st = pSeg->iFirs
281b0 74 3b 0a 20 20 4c 73 6d 50 67 6e 6f 20 69 4c 61  t;.  LsmPgno iLa
281c0 73 74 20 3d 20 70 53 65 67 2d 3e 69 4c 61 73 74  st = pSeg->iLast
281d0 50 67 3b 0a 20 20 63 68 61 72 20 2a 7a 3b 0a 0a  Pg;.  char *z;..
281e0 20 20 63 68 61 72 20 2a 7a 31 3b 0a 20 20 63 68    char *z1;.  ch
281f0 61 72 20 2a 7a 32 3b 0a 20 20 69 6e 74 20 6e 50  ar *z2;.  int nP
28200 61 64 3b 0a 0a 20 20 7a 31 20 3d 20 6c 73 6d 4d  ad;..  z1 = lsmM
28210 61 6c 6c 6f 63 50 72 69 6e 74 66 28 70 45 6e 76  allocPrintf(pEnv
28220 2c 20 22 25 64 2e 25 64 22 2c 20 69 46 69 72 73  , "%d.%d", iFirs
28230 74 2c 20 69 4c 61 73 74 29 3b 0a 20 20 69 66 28  t, iLast);.  if(
28240 20 69 52 6f 6f 74 20 29 7b 0a 20 20 20 20 7a 32   iRoot ){.    z2
28250 20 3d 20 6c 73 6d 4d 61 6c 6c 6f 63 50 72 69 6e   = lsmMallocPrin
28260 74 66 28 70 45 6e 76 2c 20 22 72 6f 6f 74 3d 25  tf(pEnv, "root=%
28270 64 22 2c 20 69 52 6f 6f 74 29 3b 0a 20 20 7d 65  d", iRoot);.  }e
28280 6c 73 65 7b 0a 20 20 20 20 7a 32 20 3d 20 6c 73  lse{.    z2 = ls
28290 6d 4d 61 6c 6c 6f 63 50 72 69 6e 74 66 28 70 45  mMallocPrintf(pE
282a0 6e 76 2c 20 22 73 69 7a 65 3d 25 64 22 2c 20 6e  nv, "size=%d", n
282b0 53 69 7a 65 29 3b 0a 20 20 7d 0a 0a 20 20 6e 50  Size);.  }..  nP
282c0 61 64 20 3d 20 6e 4d 69 6e 20 2d 20 32 20 2d 20  ad = nMin - 2 - 
282d0 73 74 72 6c 65 6e 28 7a 31 29 20 2d 20 31 20 2d  strlen(z1) - 1 -
282e0 20 73 74 72 6c 65 6e 28 7a 32 29 3b 0a 20 20 6e   strlen(z2);.  n
282f0 50 61 64 20 3d 20 4c 53 4d 5f 4d 41 58 28 30 2c  Pad = LSM_MAX(0,
28300 20 6e 50 61 64 29 3b 0a 0a 20 20 69 66 28 20 69   nPad);..  if( i
28310 52 6f 6f 74 20 29 7b 0a 20 20 20 20 7a 20 3d 20  Root ){.    z = 
28320 6c 73 6d 4d 61 6c 6c 6f 63 50 72 69 6e 74 66 28  lsmMallocPrintf(
28330 70 45 6e 76 2c 20 22 2f 25 73 20 25 2a 73 25 73  pEnv, "/%s %*s%s
28340 5c 5c 22 2c 20 7a 31 2c 20 6e 50 61 64 2c 20 22  \\", z1, nPad, "
28350 22 2c 20 7a 32 29 3b 0a 20 20 7d 65 6c 73 65 7b  ", z2);.  }else{
28360 0a 20 20 20 20 7a 20 3d 20 6c 73 6d 4d 61 6c 6c  .    z = lsmMall
28370 6f 63 50 72 69 6e 74 66 28 70 45 6e 76 2c 20 22  ocPrintf(pEnv, "
28380 7c 25 73 20 25 2a 73 25 73 7c 22 2c 20 7a 31 2c  |%s %*s%s|", z1,
28390 20 6e 50 61 64 2c 20 22 22 2c 20 7a 32 29 3b 0a   nPad, "", z2);.
283a0 20 20 7d 0a 20 20 6c 73 6d 46 72 65 65 28 70 45    }.  lsmFree(pE
283b0 6e 76 2c 20 7a 31 29 3b 0a 20 20 6c 73 6d 46 72  nv, z1);.  lsmFr
283c0 65 65 28 70 45 6e 76 2c 20 7a 32 29 3b 0a 0a 20  ee(pEnv, z2);.. 
283d0 20 72 65 74 75 72 6e 20 7a 3b 0a 7d 0a 0a 73 74   return z;.}..st
283e0 61 74 69 63 20 69 6e 74 20 66 69 6c 65 54 6f 53  atic int fileToS
283f0 74 72 69 6e 67 28 0a 20 20 6c 73 6d 5f 64 62 20  tring(.  lsm_db 
28400 2a 70 44 62 2c 20 20 20 20 20 20 20 20 20 20 20  *pDb,           
28410 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72 20           /* For 
28420 78 4d 61 6c 6c 6f 63 28 29 20 2a 2f 0a 20 20 63  xMalloc() */.  c
28430 68 61 72 20 2a 61 42 75 66 2c 20 0a 20 20 69 6e  har *aBuf, .  in
28440 74 20 6e 42 75 66 2c 20 0a 20 20 69 6e 74 20 6e  t nBuf, .  int n
28450 4d 69 6e 2c 0a 20 20 53 65 67 6d 65 6e 74 20 2a  Min,.  Segment *
28460 70 53 65 67 0a 29 7b 0a 20 20 69 6e 74 20 69 20  pSeg.){.  int i 
28470 3d 20 30 3b 0a 20 20 69 66 28 20 70 53 65 67 20  = 0;.  if( pSeg 
28480 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 65  ){.    char *zSe
28490 67 3b 0a 0a 20 20 20 20 7a 53 65 67 20 3d 20 73  g;..    zSeg = s
284a0 65 67 54 6f 53 74 72 69 6e 67 28 70 44 62 2d 3e  egToString(pDb->
284b0 70 45 6e 76 2c 20 70 53 65 67 2c 20 6e 4d 69 6e  pEnv, pSeg, nMin
284c0 29 3b 0a 20 20 20 20 73 6e 70 72 69 6e 74 66 28  );.    snprintf(
284d0 26 61 42 75 66 5b 69 5d 2c 20 6e 42 75 66 2d 69  &aBuf[i], nBuf-i
284e0 2c 20 22 25 73 22 2c 20 7a 53 65 67 29 3b 0a 20  , "%s", zSeg);. 
284f0 20 20 20 69 20 2b 3d 20 73 74 72 6c 65 6e 28 26     i += strlen(&
28500 61 42 75 66 5b 69 5d 29 3b 0a 20 20 20 20 6c 73  aBuf[i]);.    ls
28510 6d 46 72 65 65 28 70 44 62 2d 3e 70 45 6e 76 2c  mFree(pDb->pEnv,
28520 20 7a 53 65 67 29 3b 0a 0a 23 69 66 64 65 66 20   zSeg);..#ifdef 
28530 4c 53 4d 5f 4c 4f 47 5f 46 52 45 45 4c 49 53 54  LSM_LOG_FREELIST
28540 0a 20 20 20 20 6c 73 6d 49 6e 66 6f 41 72 72 61  .    lsmInfoArra
28550 79 53 74 72 75 63 74 75 72 65 28 70 44 62 2c 20  yStructure(pDb, 
28560 31 2c 20 70 53 65 67 2d 3e 69 46 69 72 73 74 2c  1, pSeg->iFirst,
28570 20 26 7a 53 65 67 29 3b 0a 20 20 20 20 73 6e 70   &zSeg);.    snp
28580 72 69 6e 74 66 28 26 61 42 75 66 5b 69 5d 2c 20  rintf(&aBuf[i], 
28590 6e 42 75 66 2d 31 2c 20 22 20 20 20 20 28 25 73  nBuf-1, "    (%s
285a0 29 22 2c 20 7a 53 65 67 29 3b 0a 20 20 20 20 69  )", zSeg);.    i
285b0 20 2b 3d 20 73 74 72 6c 65 6e 28 26 61 42 75 66   += strlen(&aBuf
285c0 5b 69 5d 29 3b 0a 20 20 20 20 6c 73 6d 46 72 65  [i]);.    lsmFre
285d0 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 7a 53 65  e(pDb->pEnv, zSe
285e0 67 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 61  g);.#endif.    a
285f0 42 75 66 5b 6e 42 75 66 5d 20 3d 20 30 3b 0a 20  Buf[nBuf] = 0;. 
28600 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 42 75 66   }else{.    aBuf
28610 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 7d 0a  [0] = '\0';.  }.
28620 0a 20 20 72 65 74 75 72 6e 20 69 3b 0a 7d 0a 0a  .  return i;.}..
28630 76 6f 69 64 20 73 6f 72 74 65 64 44 75 6d 70 50  void sortedDumpP
28640 61 67 65 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c  age(lsm_db *pDb,
28650 20 53 65 67 6d 65 6e 74 20 2a 70 52 75 6e 2c 20   Segment *pRun, 
28660 50 61 67 65 20 2a 70 50 67 2c 20 69 6e 74 20 62  Page *pPg, int b
28670 56 61 6c 73 29 7b 0a 20 20 4c 73 6d 42 6c 6f 62  Vals){.  LsmBlob
28680 20 62 6c 6f 62 20 3d 20 7b 30 2c 20 30 2c 20 30   blob = {0, 0, 0
28690 7d 3b 20 20 20 20 20 20 20 2f 2a 20 4c 73 6d 42  };       /* LsmB
286a0 6c 6f 62 20 75 73 65 64 20 66 6f 72 20 6b 65 79  lob used for key
286b0 73 20 2a 2f 0a 20 20 4c 73 6d 53 74 72 69 6e 67  s */.  LsmString
286c0 20 73 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20   s;.  int i;..  
286d0 69 6e 74 20 6e 52 65 63 3b 0a 20 20 69 6e 74 20  int nRec;.  int 
286e0 69 50 74 72 3b 0a 20 20 69 6e 74 20 66 6c 61 67  iPtr;.  int flag
286f0 73 3b 0a 20 20 75 38 20 2a 61 44 61 74 61 3b 0a  s;.  u8 *aData;.
28700 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a 0a 20 20    int nData;..  
28710 61 44 61 74 61 20 3d 20 66 73 50 61 67 65 44 61  aData = fsPageDa
28720 74 61 28 70 50 67 2c 20 26 6e 44 61 74 61 29 3b  ta(pPg, &nData);
28730 0a 0a 20 20 6e 52 65 63 20 3d 20 70 61 67 65 47  ..  nRec = pageG
28740 65 74 4e 52 65 63 28 61 44 61 74 61 2c 20 6e 44  etNRec(aData, nD
28750 61 74 61 29 3b 0a 20 20 69 50 74 72 20 3d 20 28  ata);.  iPtr = (
28760 69 6e 74 29 70 61 67 65 47 65 74 50 74 72 28 61  int)pageGetPtr(a
28770 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20  Data, nData);.  
28780 66 6c 61 67 73 20 3d 20 70 61 67 65 47 65 74 46  flags = pageGetF
28790 6c 61 67 73 28 61 44 61 74 61 2c 20 6e 44 61 74  lags(aData, nDat
287a0 61 29 3b 0a 0a 20 20 6c 73 6d 53 74 72 69 6e 67  a);..  lsmString
287b0 49 6e 69 74 28 26 73 2c 20 70 44 62 2d 3e 70 45  Init(&s, pDb->pE
287c0 6e 76 29 3b 0a 20 20 6c 73 6d 53 74 72 69 6e 67  nv);.  lsmString
287d0 41 70 70 65 6e 64 66 28 26 73 2c 22 6e 43 65 6c  Appendf(&s,"nCel
287e0 6c 3d 25 64 20 69 50 74 72 3d 25 64 20 66 6c 61  l=%d iPtr=%d fla
287f0 67 73 3d 25 64 20 7b 22 2c 20 6e 52 65 63 2c 20  gs=%d {", nRec, 
28800 69 50 74 72 2c 20 66 6c 61 67 73 29 3b 0a 20 20  iPtr, flags);.  
28810 69 66 28 20 66 6c 61 67 73 26 53 45 47 4d 45 4e  if( flags&SEGMEN
28820 54 5f 42 54 52 45 45 5f 46 4c 41 47 20 29 20 69  T_BTREE_FLAG ) i
28830 50 74 72 20 3d 20 30 3b 0a 0a 20 20 66 6f 72 28  Ptr = 0;..  for(
28840 69 3d 30 3b 20 69 3c 6e 52 65 63 3b 20 69 2b 2b  i=0; i<nRec; i++
28850 29 7b 0a 20 20 20 20 50 61 67 65 20 2a 70 52 65  ){.    Page *pRe
28860 66 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  f = 0;          
28870 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
28880 74 6f 20 70 61 67 65 20 69 52 65 66 20 2a 2f 0a  to page iRef */.
28890 20 20 20 20 69 6e 74 20 69 43 68 61 72 3b 0a 20      int iChar;. 
288a0 20 20 20 75 38 20 2a 61 4b 65 79 3b 20 69 6e 74     u8 *aKey; int
288b0 20 6e 4b 65 79 20 3d 20 30 3b 20 20 20 20 20 20   nKey = 0;      
288c0 20 2f 2a 20 4b 65 79 20 2a 2f 0a 20 20 20 20 75   /* Key */.    u
288d0 38 20 2a 61 56 61 6c 20 3d 20 30 3b 20 69 6e 74  8 *aVal = 0; int
288e0 20 6e 56 61 6c 20 3d 20 30 3b 20 20 20 2f 2a 20   nVal = 0;   /* 
288f0 56 61 6c 75 65 20 2a 2f 0a 20 20 20 20 69 6e 74  Value */.    int
28900 20 69 54 6f 70 69 63 3b 0a 20 20 20 20 75 38 20   iTopic;.    u8 
28910 2a 61 43 65 6c 6c 3b 0a 20 20 20 20 69 6e 74 20  *aCell;.    int 
28920 69 50 67 50 74 72 3b 0a 20 20 20 20 69 6e 74 20  iPgPtr;.    int 
28930 65 54 79 70 65 3b 0a 0a 20 20 20 20 61 43 65 6c  eType;..    aCel
28940 6c 20 3d 20 70 61 67 65 47 65 74 43 65 6c 6c 28  l = pageGetCell(
28950 61 44 61 74 61 2c 20 6e 44 61 74 61 2c 20 69 29  aData, nData, i)
28960 3b 0a 20 20 20 20 65 54 79 70 65 20 3d 20 2a 61  ;.    eType = *a
28970 43 65 6c 6c 2b 2b 3b 0a 20 20 20 20 61 73 73 65  Cell++;.    asse
28980 72 74 28 20 28 66 6c 61 67 73 20 26 20 53 45 47  rt( (flags & SEG
28990 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41 47 29  MENT_BTREE_FLAG)
289a0 20 7c 7c 20 65 54 79 70 65 21 3d 30 20 29 3b 0a   || eType!=0 );.
289b0 20 20 20 20 61 43 65 6c 6c 20 2b 3d 20 6c 73 6d      aCell += lsm
289c0 56 61 72 69 6e 74 47 65 74 33 32 28 61 43 65 6c  VarintGet32(aCel
289d0 6c 2c 20 26 69 50 67 50 74 72 29 3b 0a 0a 20 20  l, &iPgPtr);..  
289e0 20 20 69 66 28 20 65 54 79 70 65 3d 3d 30 20 29    if( eType==0 )
289f0 7b 0a 20 20 20 20 20 20 4c 73 6d 50 67 6e 6f 20  {.      LsmPgno 
28a00 69 52 65 66 3b 20 20 20 20 20 20 20 20 20 20 20  iRef;           
28a10 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62      /* Page numb
28a20 65 72 20 6f 66 20 72 65 66 65 72 65 6e 63 65 64  er of referenced
28a30 20 70 61 67 65 20 2a 2f 0a 20 20 20 20 20 20 61   page */.      a
28a40 43 65 6c 6c 20 2b 3d 20 6c 73 6d 56 61 72 69 6e  Cell += lsmVarin
28a50 74 47 65 74 36 34 28 61 43 65 6c 6c 2c 20 26 69  tGet64(aCell, &i
28a60 52 65 66 29 3b 0a 20 20 20 20 20 20 6c 73 6d 46  Ref);.      lsmF
28a70 73 44 62 50 61 67 65 47 65 74 28 70 44 62 2d 3e  sDbPageGet(pDb->
28a80 70 46 53 2c 20 70 52 75 6e 2c 20 69 52 65 66 2c  pFS, pRun, iRef,
28a90 20 26 70 52 65 66 29 3b 0a 20 20 20 20 20 20 61   &pRef);.      a
28aa0 4b 65 79 20 3d 20 70 61 67 65 47 65 74 4b 65 79  Key = pageGetKey
28ab0 28 70 52 75 6e 2c 20 70 52 65 66 2c 20 30 2c 20  (pRun, pRef, 0, 
28ac0 26 69 54 6f 70 69 63 2c 20 26 6e 4b 65 79 2c 20  &iTopic, &nKey, 
28ad0 26 62 6c 6f 62 29 3b 0a 20 20 20 20 7d 65 6c 73  &blob);.    }els
28ae0 65 7b 0a 20 20 20 20 20 20 61 43 65 6c 6c 20 2b  e{.      aCell +
28af0 3d 20 6c 73 6d 56 61 72 69 6e 74 47 65 74 33 32  = lsmVarintGet32
28b00 28 61 43 65 6c 6c 2c 20 26 6e 4b 65 79 29 3b 0a  (aCell, &nKey);.
28b10 20 20 20 20 20 20 69 66 28 20 72 74 49 73 57 72        if( rtIsWr
28b20 69 74 65 28 65 54 79 70 65 29 20 29 20 61 43 65  ite(eType) ) aCe
28b30 6c 6c 20 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 47  ll += lsmVarintG
28b40 65 74 33 32 28 61 43 65 6c 6c 2c 20 26 6e 56 61  et32(aCell, &nVa
28b50 6c 29 3b 0a 20 20 20 20 20 20 73 6f 72 74 65 64  l);.      sorted
28b60 52 65 61 64 44 61 74 61 28 30 2c 20 70 50 67 2c  ReadData(0, pPg,
28b70 20 28 61 43 65 6c 6c 2d 61 44 61 74 61 29 2c 20   (aCell-aData), 
28b80 6e 4b 65 79 2b 6e 56 61 6c 2c 20 28 76 6f 69 64  nKey+nVal, (void
28b90 20 2a 2a 29 26 61 4b 65 79 2c 20 26 62 6c 6f 62   **)&aKey, &blob
28ba0 29 3b 0a 20 20 20 20 20 20 61 56 61 6c 20 3d 20  );.      aVal = 
28bb0 26 61 4b 65 79 5b 6e 4b 65 79 5d 3b 0a 20 20 20  &aKey[nKey];.   
28bc0 20 20 20 69 54 6f 70 69 63 20 3d 20 65 54 79 70     iTopic = eTyp
28bd0 65 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 6c 73  e;.    }..    ls
28be0 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26  mStringAppendf(&
28bf0 73 2c 20 22 25 73 25 32 58 3a 22 2c 20 28 69 3d  s, "%s%2X:", (i=
28c00 3d 30 3f 22 22 3a 22 20 22 29 2c 20 69 54 6f 70  =0?"":" "), iTop
28c10 69 63 29 3b 0a 20 20 20 20 66 6f 72 28 69 43 68  ic);.    for(iCh
28c20 61 72 3d 30 3b 20 69 43 68 61 72 3c 6e 4b 65 79  ar=0; iChar<nKey
28c30 3b 20 69 43 68 61 72 2b 2b 29 7b 0a 20 20 20 20  ; iChar++){.    
28c40 20 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e    lsmStringAppen
28c50 64 66 28 26 73 2c 20 22 25 63 22 2c 20 69 73 61  df(&s, "%c", isa
28c60 6c 6e 75 6d 28 61 4b 65 79 5b 69 43 68 61 72 5d  lnum(aKey[iChar]
28c70 29 20 3f 20 61 4b 65 79 5b 69 43 68 61 72 5d 20  ) ? aKey[iChar] 
28c80 3a 20 27 2e 27 29 3b 0a 20 20 20 20 7d 0a 20 20  : '.');.    }.  
28c90 20 20 69 66 28 20 6e 56 61 6c 3e 30 20 26 26 20    if( nVal>0 && 
28ca0 62 56 61 6c 73 20 29 7b 0a 20 20 20 20 20 20 6c  bVals ){.      l
28cb0 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28  smStringAppendf(
28cc0 26 73 2c 20 22 23 23 22 29 3b 0a 20 20 20 20 20  &s, "##");.     
28cd0 20 66 6f 72 28 69 43 68 61 72 3d 30 3b 20 69 43   for(iChar=0; iC
28ce0 68 61 72 3c 6e 56 61 6c 3b 20 69 43 68 61 72 2b  har<nVal; iChar+
28cf0 2b 29 7b 0a 20 20 20 20 20 20 20 20 6c 73 6d 53  +){.        lsmS
28d00 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73 2c  tringAppendf(&s,
28d10 20 22 25 63 22 2c 20 69 73 61 6c 6e 75 6d 28 61   "%c", isalnum(a
28d20 56 61 6c 5b 69 43 68 61 72 5d 29 20 3f 20 61 56  Val[iChar]) ? aV
28d30 61 6c 5b 69 43 68 61 72 5d 20 3a 20 27 2e 27 29  al[iChar] : '.')
28d40 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
28d50 0a 20 20 20 20 6c 73 6d 53 74 72 69 6e 67 41 70  .    lsmStringAp
28d60 70 65 6e 64 66 28 26 73 2c 20 22 20 25 64 22 2c  pendf(&s, " %d",
28d70 20 69 50 67 50 74 72 2b 69 50 74 72 29 3b 0a 20   iPgPtr+iPtr);. 
28d80 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65     lsmFsPageRele
28d90 61 73 65 28 70 52 65 66 29 3b 0a 20 20 7d 0a 20  ase(pRef);.  }. 
28da0 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64   lsmStringAppend
28db0 28 26 73 2c 20 22 7d 22 2c 20 31 29 3b 0a 0a 20  (&s, "}", 1);.. 
28dc0 20 6c 73 6d 4c 6f 67 4d 65 73 73 61 67 65 28 70   lsmLogMessage(p
28dd0 44 62 2c 20 4c 53 4d 5f 4f 4b 2c 20 22 20 20 20  Db, LSM_OK, "   
28de0 20 20 20 50 61 67 65 20 25 64 3a 20 25 73 22 2c     Page %d: %s",
28df0 20 6c 73 6d 46 73 50 61 67 65 4e 75 6d 62 65 72   lsmFsPageNumber
28e00 28 70 50 67 29 2c 20 73 2e 7a 29 3b 0a 20 20 6c  (pPg), s.z);.  l
28e10 73 6d 53 74 72 69 6e 67 43 6c 65 61 72 28 26 73  smStringClear(&s
28e20 29 3b 0a 0a 20 20 73 6f 72 74 65 64 42 6c 6f 62  );..  sortedBlob
28e30 46 72 65 65 28 26 62 6c 6f 62 29 3b 0a 7d 0a 0a  Free(&blob);.}..
28e40 73 74 61 74 69 63 20 76 6f 69 64 20 69 6e 66 6f  static void info
28e50 43 65 6c 6c 44 75 6d 70 28 0a 20 20 6c 73 6d 5f  CellDump(.  lsm_
28e60 64 62 20 2a 70 44 62 2c 20 20 20 20 20 20 20 20  db *pDb,        
28e70 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
28e80 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a  atabase handle *
28e90 2f 0a 20 20 53 65 67 6d 65 6e 74 20 2a 70 53 65  /.  Segment *pSe
28ea0 67 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  g,              
28eb0 20 20 20 20 2f 2a 20 53 65 67 6d 65 6e 74 20 70      /* Segment p
28ec0 61 67 65 20 62 65 6c 6f 6e 67 73 20 74 6f 20 2a  age belongs to *
28ed0 2f 0a 20 20 69 6e 74 20 62 49 6e 64 69 72 65 63  /.  int bIndirec
28ee0 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
28ef0 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 66      /* True to f
28f00 6f 6c 6c 6f 77 20 69 6e 64 69 72 65 63 74 20 72  ollow indirect r
28f10 65 66 73 20 2a 2f 0a 20 20 50 61 67 65 20 2a 70  efs */.  Page *p
28f20 50 67 2c 0a 20 20 69 6e 74 20 69 43 65 6c 6c 2c  Pg,.  int iCell,
28f30 0a 20 20 69 6e 74 20 2a 70 65 54 79 70 65 2c 0a  .  int *peType,.
28f40 20 20 69 6e 74 20 2a 70 69 50 67 50 74 72 2c 0a    int *piPgPtr,.
28f50 20 20 75 38 20 2a 2a 70 61 4b 65 79 2c 20 69 6e    u8 **paKey, in
28f60 74 20 2a 70 6e 4b 65 79 2c 0a 20 20 75 38 20 2a  t *pnKey,.  u8 *
28f70 2a 70 61 56 61 6c 2c 20 69 6e 74 20 2a 70 6e 56  *paVal, int *pnV
28f80 61 6c 2c 0a 20 20 4c 73 6d 42 6c 6f 62 20 2a 70  al,.  LsmBlob *p
28f90 42 6c 6f 62 0a 29 7b 0a 20 20 75 38 20 2a 61 44  Blob.){.  u8 *aD
28fa0 61 74 61 3b 20 69 6e 74 20 6e 44 61 74 61 3b 20  ata; int nData; 
28fb0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67            /* Pag
28fc0 65 20 64 61 74 61 20 2a 2f 0a 20 20 75 38 20 2a  e data */.  u8 *
28fd0 61 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79 20 3d  aKey; int nKey =
28fe0 20 30 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 4b   0;         /* K
28ff0 65 79 20 2a 2f 0a 20 20 75 38 20 2a 61 56 61 6c  ey */.  u8 *aVal
29000 20 3d 20 30 3b 20 69 6e 74 20 6e 56 61 6c 20 3d   = 0; int nVal =
29010 20 30 3b 20 20 20 20 20 2f 2a 20 56 61 6c 75 65   0;     /* Value
29020 20 2a 2f 0a 20 20 69 6e 74 20 65 54 79 70 65 3b   */.  int eType;
29030 0a 20 20 69 6e 74 20 69 50 67 50 74 72 3b 0a 20  .  int iPgPtr;. 
29040 20 50 61 67 65 20 2a 70 52 65 66 20 3d 20 30 3b   Page *pRef = 0;
29050 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29060 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 70   /* Pointer to p
29070 61 67 65 20 69 52 65 66 20 2a 2f 0a 20 20 75 38  age iRef */.  u8
29080 20 2a 61 43 65 6c 6c 3b 0a 0a 20 20 61 44 61 74   *aCell;..  aDat
29090 61 20 3d 20 66 73 50 61 67 65 44 61 74 61 28 70  a = fsPageData(p
290a0 50 67 2c 20 26 6e 44 61 74 61 29 3b 0a 0a 20 20  Pg, &nData);..  
290b0 61 43 65 6c 6c 20 3d 20 70 61 67 65 47 65 74 43  aCell = pageGetC
290c0 65 6c 6c 28 61 44 61 74 61 2c 20 6e 44 61 74 61  ell(aData, nData
290d0 2c 20 69 43 65 6c 6c 29 3b 0a 20 20 65 54 79 70  , iCell);.  eTyp
290e0 65 20 3d 20 2a 61 43 65 6c 6c 2b 2b 3b 0a 20 20  e = *aCell++;.  
290f0 61 43 65 6c 6c 20 2b 3d 20 6c 73 6d 56 61 72 69  aCell += lsmVari
29100 6e 74 47 65 74 33 32 28 61 43 65 6c 6c 2c 20 26  ntGet32(aCell, &
29110 69 50 67 50 74 72 29 3b 0a 0a 20 20 69 66 28 20  iPgPtr);..  if( 
29120 65 54 79 70 65 3d 3d 30 20 29 7b 0a 20 20 20 20  eType==0 ){.    
29130 69 6e 74 20 64 75 6d 6d 79 3b 0a 20 20 20 20 4c  int dummy;.    L
29140 73 6d 50 67 6e 6f 20 69 52 65 66 3b 20 20 20 20  smPgno iRef;    
29150 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
29160 50 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 72  Page number of r
29170 65 66 65 72 65 6e 63 65 64 20 70 61 67 65 20 2a  eferenced page *
29180 2f 0a 20 20 20 20 61 43 65 6c 6c 20 2b 3d 20 6c  /.    aCell += l
29190 73 6d 56 61 72 69 6e 74 47 65 74 36 34 28 61 43  smVarintGet64(aC
291a0 65 6c 6c 2c 20 26 69 52 65 66 29 3b 0a 20 20 20  ell, &iRef);.   
291b0 20 69 66 28 20 62 49 6e 64 69 72 65 63 74 20 29   if( bIndirect )
291c0 7b 0a 20 20 20 20 20 20 6c 73 6d 46 73 44 62 50  {.      lsmFsDbP
291d0 61 67 65 47 65 74 28 70 44 62 2d 3e 70 46 53 2c  ageGet(pDb->pFS,
291e0 20 70 53 65 67 2c 20 69 52 65 66 2c 20 26 70 52   pSeg, iRef, &pR
291f0 65 66 29 3b 0a 20 20 20 20 20 20 70 61 67 65 47  ef);.      pageG
29200 65 74 4b 65 79 43 6f 70 79 28 70 44 62 2d 3e 70  etKeyCopy(pDb->p
29210 45 6e 76 2c 20 70 53 65 67 2c 20 70 52 65 66 2c  Env, pSeg, pRef,
29220 20 30 2c 20 26 64 75 6d 6d 79 2c 20 70 42 6c 6f   0, &dummy, pBlo
29230 62 29 3b 0a 20 20 20 20 20 20 61 4b 65 79 20 3d  b);.      aKey =
29240 20 28 75 38 20 2a 29 70 42 6c 6f 62 2d 3e 70 44   (u8 *)pBlob->pD
29250 61 74 61 3b 0a 20 20 20 20 20 20 6e 4b 65 79 20  ata;.      nKey 
29260 3d 20 70 42 6c 6f 62 2d 3e 6e 44 61 74 61 3b 0a  = pBlob->nData;.
29270 20 20 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52        lsmFsPageR
29280 65 6c 65 61 73 65 28 70 52 65 66 29 3b 0a 20 20  elease(pRef);.  
29290 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 61    }else{.      a
292a0 4b 65 79 20 3d 20 28 75 38 20 2a 29 22 3c 69 6e  Key = (u8 *)"<in
292b0 64 69 72 65 63 74 3e 22 3b 0a 20 20 20 20 20 20  direct>";.      
292c0 6e 4b 65 79 20 3d 20 31 31 3b 0a 20 20 20 20 7d  nKey = 11;.    }
292d0 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 43  .  }else{.    aC
292e0 65 6c 6c 20 2b 3d 20 6c 73 6d 56 61 72 69 6e 74  ell += lsmVarint
292f0 47 65 74 33 32 28 61 43 65 6c 6c 2c 20 26 6e 4b  Get32(aCell, &nK
29300 65 79 29 3b 0a 20 20 20 20 69 66 28 20 72 74 49  ey);.    if( rtI
29310 73 57 72 69 74 65 28 65 54 79 70 65 29 20 29 20  sWrite(eType) ) 
29320 61 43 65 6c 6c 20 2b 3d 20 6c 73 6d 56 61 72 69  aCell += lsmVari
29330 6e 74 47 65 74 33 32 28 61 43 65 6c 6c 2c 20 26  ntGet32(aCell, &
29340 6e 56 61 6c 29 3b 0a 20 20 20 20 73 6f 72 74 65  nVal);.    sorte
29350 64 52 65 61 64 44 61 74 61 28 70 53 65 67 2c 20  dReadData(pSeg, 
29360 70 50 67 2c 20 28 61 43 65 6c 6c 2d 61 44 61 74  pPg, (aCell-aDat
29370 61 29 2c 20 6e 4b 65 79 2b 6e 56 61 6c 2c 20 28  a), nKey+nVal, (
29380 76 6f 69 64 20 2a 2a 29 26 61 4b 65 79 2c 20 70  void **)&aKey, p
29390 42 6c 6f 62 29 3b 0a 20 20 20 20 61 56 61 6c 20  Blob);.    aVal 
293a0 3d 20 26 61 4b 65 79 5b 6e 4b 65 79 5d 3b 0a 20  = &aKey[nKey];. 
293b0 20 7d 0a 0a 20 20 69 66 28 20 70 65 54 79 70 65   }..  if( peType
293c0 20 29 20 2a 70 65 54 79 70 65 20 3d 20 65 54 79   ) *peType = eTy
293d0 70 65 3b 0a 20 20 69 66 28 20 70 69 50 67 50 74  pe;.  if( piPgPt
293e0 72 20 29 20 2a 70 69 50 67 50 74 72 20 3d 20 69  r ) *piPgPtr = i
293f0 50 67 50 74 72 3b 0a 20 20 69 66 28 20 70 61 4b  PgPtr;.  if( paK
29400 65 79 20 29 20 2a 70 61 4b 65 79 20 3d 20 61 4b  ey ) *paKey = aK
29410 65 79 3b 0a 20 20 69 66 28 20 70 61 56 61 6c 20  ey;.  if( paVal 
29420 29 20 2a 70 61 56 61 6c 20 3d 20 61 56 61 6c 3b  ) *paVal = aVal;
29430 0a 20 20 69 66 28 20 70 6e 4b 65 79 20 29 20 2a  .  if( pnKey ) *
29440 70 6e 4b 65 79 20 3d 20 6e 4b 65 79 3b 0a 20 20  pnKey = nKey;.  
29450 69 66 28 20 70 6e 56 61 6c 20 29 20 2a 70 6e 56  if( pnVal ) *pnV
29460 61 6c 20 3d 20 6e 56 61 6c 3b 0a 7d 0a 0a 73 74  al = nVal;.}..st
29470 61 74 69 63 20 69 6e 74 20 69 6e 66 6f 41 70 70  atic int infoApp
29480 65 6e 64 42 6c 6f 62 28 4c 73 6d 53 74 72 69 6e  endBlob(LsmStrin
29490 67 20 2a 70 53 74 72 2c 20 69 6e 74 20 62 48 65  g *pStr, int bHe
294a0 78 2c 20 75 38 20 2a 7a 2c 20 69 6e 74 20 6e 29  x, u8 *z, int n)
294b0 7b 0a 20 20 69 6e 74 20 69 43 68 61 72 3b 0a 20  {.  int iChar;. 
294c0 20 66 6f 72 28 69 43 68 61 72 3d 30 3b 20 69 43   for(iChar=0; iC
294d0 68 61 72 3c 6e 3b 20 69 43 68 61 72 2b 2b 29 7b  har<n; iChar++){
294e0 0a 20 20 20 20 69 66 28 20 62 48 65 78 20 29 7b  .    if( bHex ){
294f0 0a 20 20 20 20 20 20 6c 73 6d 53 74 72 69 6e 67  .      lsmString
29500 41 70 70 65 6e 64 66 28 70 53 74 72 2c 20 22 25  Appendf(pStr, "%
29510 30 32 58 22 2c 20 7a 5b 69 43 68 61 72 5d 29 3b  02X", z[iChar]);
29520 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
29530 20 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e    lsmStringAppen
29540 64 66 28 70 53 74 72 2c 20 22 25 63 22 2c 20 69  df(pStr, "%c", i
29550 73 61 6c 6e 75 6d 28 7a 5b 69 43 68 61 72 5d 29  salnum(z[iChar])
29560 20 3f 7a 5b 69 43 68 61 72 5d 20 3a 20 27 2e 27   ?z[iChar] : '.'
29570 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72  );.    }.  }.  r
29580 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 7d 0a  eturn LSM_OK;.}.
29590 0a 23 64 65 66 69 6e 65 20 49 4e 46 4f 5f 50 41  .#define INFO_PA
295a0 47 45 5f 44 55 4d 50 5f 44 41 54 41 20 20 20 20  GE_DUMP_DATA    
295b0 20 30 78 30 31 0a 23 64 65 66 69 6e 65 20 49 4e   0x01.#define IN
295c0 46 4f 5f 50 41 47 45 5f 44 55 4d 50 5f 56 41 4c  FO_PAGE_DUMP_VAL
295d0 55 45 53 20 20 20 30 78 30 32 0a 23 64 65 66 69  UES   0x02.#defi
295e0 6e 65 20 49 4e 46 4f 5f 50 41 47 45 5f 44 55 4d  ne INFO_PAGE_DUM
295f0 50 5f 48 45 58 20 20 20 20 20 20 30 78 30 34 0a  P_HEX      0x04.
29600 23 64 65 66 69 6e 65 20 49 4e 46 4f 5f 50 41 47  #define INFO_PAG
29610 45 5f 44 55 4d 50 5f 49 4e 44 49 52 45 43 54 20  E_DUMP_INDIRECT 
29620 30 78 30 38 0a 0a 73 74 61 74 69 63 20 69 6e 74  0x08..static int
29630 20 69 6e 66 6f 50 61 67 65 44 75 6d 70 28 0a 20   infoPageDump(. 
29640 20 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20   lsm_db *pDb,   
29650 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29660 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e   /* Database han
29670 64 6c 65 20 2a 2f 0a 20 20 4c 73 6d 50 67 6e 6f  dle */.  LsmPgno
29680 20 69 50 67 2c 20 20 20 20 20 20 20 20 20 20 20   iPg,           
29690 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65           /* Page
296a0 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 20   number of page 
296b0 74 6f 20 64 75 6d 70 20 2a 2f 0a 20 20 69 6e 74  to dump */.  int
296c0 20 66 6c 61 67 73 2c 0a 20 20 63 68 61 72 20 2a   flags,.  char *
296d0 2a 70 7a 4f 75 74 20 20 20 20 20 20 20 20 20 20  *pzOut          
296e0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
296f0 3a 20 6c 73 6d 4d 61 6c 6c 6f 63 27 64 20 73 74  : lsmMalloc'd st
29700 72 69 6e 67 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  ring */.){.  int
29710 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20   rc = LSM_OK;   
29720 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
29730 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
29740 20 50 61 67 65 20 2a 70 50 67 20 3d 20 30 3b 20   Page *pPg = 0; 
29750 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29760 20 2f 2a 20 48 61 6e 64 6c 65 20 66 6f 72 20 70   /* Handle for p
29770 61 67 65 20 69 50 67 20 2a 2f 0a 20 20 69 6e 74  age iPg */.  int
29780 20 69 2c 20 6a 3b 20 20 20 20 20 20 20 20 20 20   i, j;          
29790 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
297a0 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 73 20 2a 2f  Loop counters */
297b0 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20 70 65 72  .  const int per
297c0 4c 69 6e 65 20 3d 20 31 36 3b 20 20 20 20 20 20  Line = 16;      
297d0 20 20 20 2f 2a 20 42 79 74 65 73 20 70 65 72 20     /* Bytes per 
297e0 6c 69 6e 65 20 69 6e 20 74 68 65 20 72 61 77 20  line in the raw 
297f0 68 65 78 20 64 75 6d 70 20 2a 2f 0a 20 20 53 65  hex dump */.  Se
29800 67 6d 65 6e 74 20 2a 70 53 65 67 20 3d 20 30 3b  gment *pSeg = 0;
29810 0a 20 20 53 6e 61 70 73 68 6f 74 20 2a 70 53 6e  .  Snapshot *pSn
29820 61 70 3b 0a 0a 20 20 69 6e 74 20 62 56 61 6c 75  ap;..  int bValu
29830 65 73 20 3d 20 28 66 6c 61 67 73 20 26 20 49 4e  es = (flags & IN
29840 46 4f 5f 50 41 47 45 5f 44 55 4d 50 5f 56 41 4c  FO_PAGE_DUMP_VAL
29850 55 45 53 29 3b 0a 20 20 69 6e 74 20 62 48 65 78  UES);.  int bHex
29860 20 3d 20 28 66 6c 61 67 73 20 26 20 49 4e 46 4f   = (flags & INFO
29870 5f 50 41 47 45 5f 44 55 4d 50 5f 48 45 58 29 3b  _PAGE_DUMP_HEX);
29880 0a 20 20 69 6e 74 20 62 44 61 74 61 20 3d 20 28  .  int bData = (
29890 66 6c 61 67 73 20 26 20 49 4e 46 4f 5f 50 41 47  flags & INFO_PAG
298a0 45 5f 44 55 4d 50 5f 44 41 54 41 29 3b 0a 20 20  E_DUMP_DATA);.  
298b0 69 6e 74 20 62 49 6e 64 69 72 65 63 74 20 3d 20  int bIndirect = 
298c0 28 66 6c 61 67 73 20 26 20 49 4e 46 4f 5f 50 41  (flags & INFO_PA
298d0 47 45 5f 44 55 4d 50 5f 49 4e 44 49 52 45 43 54  GE_DUMP_INDIRECT
298e0 29 3b 0a 0a 20 20 2a 70 7a 4f 75 74 20 3d 20 30  );..  *pzOut = 0
298f0 3b 0a 20 20 69 66 28 20 69 50 67 3d 3d 30 20 29  ;.  if( iPg==0 )
29900 20 72 65 74 75 72 6e 20 4c 53 4d 5f 45 52 52 4f   return LSM_ERRO
29910 52 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 44  R;..  assert( pD
29920 62 2d 3e 70 43 6c 69 65 6e 74 20 7c 7c 20 70 44  b->pClient || pD
29930 62 2d 3e 70 57 6f 72 6b 65 72 20 29 3b 0a 20 20  b->pWorker );.  
29940 70 53 6e 61 70 20 3d 20 70 44 62 2d 3e 70 43 6c  pSnap = pDb->pCl
29950 69 65 6e 74 3b 0a 20 20 69 66 28 20 70 53 6e 61  ient;.  if( pSna
29960 70 3d 3d 30 20 29 20 70 53 6e 61 70 20 3d 20 70  p==0 ) pSnap = p
29970 44 62 2d 3e 70 57 6f 72 6b 65 72 3b 0a 20 20 69  Db->pWorker;.  i
29980 66 28 20 70 53 6e 61 70 2d 3e 72 65 64 69 72 65  f( pSnap->redire
29990 63 74 2e 6e 3e 30 20 29 7b 0a 20 20 20 20 4c 65  ct.n>0 ){.    Le
299a0 76 65 6c 20 2a 70 4c 76 6c 3b 0a 20 20 20 20 69  vel *pLvl;.    i
299b0 6e 74 20 62 55 73 65 20 3d 20 30 3b 0a 20 20 20  nt bUse = 0;.   
299c0 20 66 6f 72 28 70 4c 76 6c 3d 70 53 6e 61 70 2d   for(pLvl=pSnap-
299d0 3e 70 4c 65 76 65 6c 3b 20 70 4c 76 6c 2d 3e 70  >pLevel; pLvl->p
299e0 4e 65 78 74 3b 20 70 4c 76 6c 3d 70 4c 76 6c 2d  Next; pLvl=pLvl-
299f0 3e 70 4e 65 78 74 29 3b 0a 20 20 20 20 70 53 65  >pNext);.    pSe
29a00 67 20 3d 20 28 70 4c 76 6c 2d 3e 6e 52 69 67 68  g = (pLvl->nRigh
29a10 74 3d 3d 30 20 3f 20 26 70 4c 76 6c 2d 3e 6c 68  t==0 ? &pLvl->lh
29a20 73 20 3a 20 26 70 4c 76 6c 2d 3e 61 52 68 73 5b  s : &pLvl->aRhs[
29a30 70 4c 76 6c 2d 3e 6e 52 69 67 68 74 2d 31 5d 29  pLvl->nRight-1])
29a40 3b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73  ;.    rc = lsmFs
29a50 53 65 67 6d 65 6e 74 43 6f 6e 74 61 69 6e 73 50  SegmentContainsP
29a60 67 28 70 44 62 2d 3e 70 46 53 2c 20 70 53 65 67  g(pDb->pFS, pSeg
29a70 2c 20 69 50 67 2c 20 26 62 55 73 65 29 3b 0a 20  , iPg, &bUse);. 
29a80 20 20 20 69 66 28 20 62 55 73 65 3d 3d 30 20 29     if( bUse==0 )
29a90 7b 0a 20 20 20 20 20 20 70 53 65 67 20 3d 20 30  {.      pSeg = 0
29aa0 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  ;.    }.  }..  /
29ab0 2a 20 69 50 67 20 69 73 20 61 20 72 65 61 6c 20  * iPg is a real 
29ac0 70 61 67 65 20 6e 75 6d 62 65 72 20 28 6e 6f 74  page number (not
29ad0 20 73 75 62 6a 65 63 74 20 74 6f 20 72 65 64 69   subject to redi
29ae0 72 65 63 74 69 6f 6e 29 2e 20 53 6f 20 69 74 20  rection). So it 
29af0 69 73 20 73 61 66 65 20 0a 20 20 2a 2a 20 74 6f  is safe .  ** to
29b00 20 70 61 73 73 20 61 20 4e 55 4c 4c 20 69 6e 20   pass a NULL in 
29b10 70 6c 61 63 65 20 6f 66 20 74 68 65 20 73 65 67  place of the seg
29b20 6d 65 6e 74 20 70 6f 69 6e 74 65 72 20 61 73 20  ment pointer as 
29b30 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d  the second argum
29b40 65 6e 74 0a 20 20 2a 2a 20 74 6f 20 6c 73 6d 46  ent.  ** to lsmF
29b50 73 44 62 50 61 67 65 47 65 74 28 29 20 68 65 72  sDbPageGet() her
29b60 65 2e 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d  e.  */.  if( rc=
29b70 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  =LSM_OK ){.    r
29b80 63 20 3d 20 6c 73 6d 46 73 44 62 50 61 67 65 47  c = lsmFsDbPageG
29b90 65 74 28 70 44 62 2d 3e 70 46 53 2c 20 30 2c 20  et(pDb->pFS, 0, 
29ba0 69 50 67 2c 20 26 70 50 67 29 3b 0a 20 20 7d 0a  iPg, &pPg);.  }.
29bb0 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f  .  if( rc==LSM_O
29bc0 4b 20 29 7b 0a 20 20 20 20 4c 73 6d 42 6c 6f 62  K ){.    LsmBlob
29bd0 20 62 6c 6f 62 20 3d 20 7b 30 2c 20 30 2c 20 30   blob = {0, 0, 0
29be0 2c 20 30 7d 3b 0a 20 20 20 20 69 6e 74 20 6e 4b  , 0};.    int nK
29bf0 65 79 57 69 64 74 68 20 3d 20 30 3b 0a 20 20 20  eyWidth = 0;.   
29c00 20 4c 73 6d 53 74 72 69 6e 67 20 73 74 72 3b 0a   LsmString str;.
29c10 20 20 20 20 69 6e 74 20 6e 52 65 63 3b 0a 20 20      int nRec;.  
29c20 20 20 69 6e 74 20 69 50 74 72 3b 0a 20 20 20 20    int iPtr;.    
29c30 69 6e 74 20 66 6c 61 67 73 32 3b 0a 20 20 20 20  int flags2;.    
29c40 69 6e 74 20 69 43 65 6c 6c 3b 0a 20 20 20 20 75  int iCell;.    u
29c50 38 20 2a 61 44 61 74 61 3b 20 69 6e 74 20 6e 44  8 *aData; int nD
29c60 61 74 61 3b 20 20 20 20 20 20 20 20 20 2f 2a 20  ata;         /* 
29c70 50 61 67 65 20 64 61 74 61 20 61 6e 64 20 73 69  Page data and si
29c80 7a 65 20 74 68 65 72 65 6f 66 20 2a 2f 0a 0a 20  ze thereof */.. 
29c90 20 20 20 61 44 61 74 61 20 3d 20 66 73 50 61 67     aData = fsPag
29ca0 65 44 61 74 61 28 70 50 67 2c 20 26 6e 44 61 74  eData(pPg, &nDat
29cb0 61 29 3b 0a 20 20 20 20 6e 52 65 63 20 3d 20 70  a);.    nRec = p
29cc0 61 67 65 47 65 74 4e 52 65 63 28 61 44 61 74 61  ageGetNRec(aData
29cd0 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 69 50  , nData);.    iP
29ce0 74 72 20 3d 20 28 69 6e 74 29 70 61 67 65 47 65  tr = (int)pageGe
29cf0 74 50 74 72 28 61 44 61 74 61 2c 20 6e 44 61 74  tPtr(aData, nDat
29d00 61 29 3b 0a 20 20 20 20 66 6c 61 67 73 32 20 3d  a);.    flags2 =
29d10 20 70 61 67 65 47 65 74 46 6c 61 67 73 28 61 44   pageGetFlags(aD
29d20 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 0a 20 20  ata, nData);..  
29d30 20 20 6c 73 6d 53 74 72 69 6e 67 49 6e 69 74 28    lsmStringInit(
29d40 26 73 74 72 2c 20 70 44 62 2d 3e 70 45 6e 76 29  &str, pDb->pEnv)
29d50 3b 0a 20 20 20 20 6c 73 6d 53 74 72 69 6e 67 41  ;.    lsmStringA
29d60 70 70 65 6e 64 66 28 26 73 74 72 2c 20 22 50 61  ppendf(&str, "Pa
29d70 67 65 20 3a 20 25 6c 6c 64 20 20 28 25 64 20 62  ge : %lld  (%d b
29d80 79 74 65 73 29 5c 6e 22 2c 20 69 50 67 2c 20 6e  ytes)\n", iPg, n
29d90 44 61 74 61 29 3b 0a 20 20 20 20 6c 73 6d 53 74  Data);.    lsmSt
29da0 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73 74 72  ringAppendf(&str
29db0 2c 20 22 6e 52 65 63 20 3a 20 25 64 5c 6e 22 2c  , "nRec : %d\n",
29dc0 20 6e 52 65 63 29 3b 0a 20 20 20 20 6c 73 6d 53   nRec);.    lsmS
29dd0 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73 74  tringAppendf(&st
29de0 72 2c 20 22 69 50 74 72 20 3a 20 25 64 5c 6e 22  r, "iPtr : %d\n"
29df0 2c 20 69 50 74 72 29 3b 0a 20 20 20 20 6c 73 6d  , iPtr);.    lsm
29e00 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73  StringAppendf(&s
29e10 74 72 2c 20 22 66 6c 61 67 73 3a 20 25 30 34 78  tr, "flags: %04x
29e20 5c 6e 22 2c 20 66 6c 61 67 73 32 29 3b 0a 20 20  \n", flags2);.  
29e30 20 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e    lsmStringAppen
29e40 64 66 28 26 73 74 72 2c 20 22 5c 6e 22 29 3b 0a  df(&str, "\n");.
29e50 0a 20 20 20 20 66 6f 72 28 69 43 65 6c 6c 3d 30  .    for(iCell=0
29e60 3b 20 69 43 65 6c 6c 3c 6e 52 65 63 3b 20 69 43  ; iCell<nRec; iC
29e70 65 6c 6c 2b 2b 29 7b 0a 20 20 20 20 20 20 69 6e  ell++){.      in
29e80 74 20 6e 4b 65 79 3b 0a 20 20 20 20 20 20 69 6e  t nKey;.      in
29e90 66 6f 43 65 6c 6c 44 75 6d 70 28 0a 20 20 20 20  foCellDump(.    
29ea0 20 20 20 20 20 20 70 44 62 2c 20 70 53 65 67 2c        pDb, pSeg,
29eb0 20 62 49 6e 64 69 72 65 63 74 2c 20 70 50 67 2c   bIndirect, pPg,
29ec0 20 69 43 65 6c 6c 2c 20 30 2c 20 30 2c 20 30 2c   iCell, 0, 0, 0,
29ed0 20 26 6e 4b 65 79 2c 20 30 2c 20 30 2c 20 26 62   &nKey, 0, 0, &b
29ee0 6c 6f 62 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  lob.      );.   
29ef0 20 20 20 69 66 28 20 6e 4b 65 79 3e 6e 4b 65 79     if( nKey>nKey
29f00 57 69 64 74 68 20 29 20 6e 4b 65 79 57 69 64 74  Width ) nKeyWidt
29f10 68 20 3d 20 6e 4b 65 79 3b 0a 20 20 20 20 7d 0a  h = nKey;.    }.
29f20 20 20 20 20 69 66 28 20 62 48 65 78 20 29 20 6e      if( bHex ) n
29f30 4b 65 79 57 69 64 74 68 20 3d 20 6e 4b 65 79 57  KeyWidth = nKeyW
29f40 69 64 74 68 20 2a 20 32 3b 0a 0a 20 20 20 20 66  idth * 2;..    f
29f50 6f 72 28 69 43 65 6c 6c 3d 30 3b 20 69 43 65 6c  or(iCell=0; iCel
29f60 6c 3c 6e 52 65 63 3b 20 69 43 65 6c 6c 2b 2b 29  l<nRec; iCell++)
29f70 7b 0a 20 20 20 20 20 20 75 38 20 2a 61 4b 65 79  {.      u8 *aKey
29f80 3b 20 69 6e 74 20 6e 4b 65 79 20 3d 20 30 3b 20  ; int nKey = 0; 
29f90 20 20 20 20 20 20 2f 2a 20 4b 65 79 20 2a 2f 0a        /* Key */.
29fa0 20 20 20 20 20 20 75 38 20 2a 61 56 61 6c 3b 20        u8 *aVal; 
29fb0 69 6e 74 20 6e 56 61 6c 20 3d 20 30 3b 20 20 20  int nVal = 0;   
29fc0 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 2a 2f 0a      /* Value */.
29fd0 20 20 20 20 20 20 69 6e 74 20 69 50 67 50 74 72        int iPgPtr
29fe0 3b 0a 20 20 20 20 20 20 69 6e 74 20 65 54 79 70  ;.      int eTyp
29ff0 65 3b 0a 20 20 20 20 20 20 4c 73 6d 50 67 6e 6f  e;.      LsmPgno
2a000 20 69 41 62 73 50 74 72 3b 0a 20 20 20 20 20 20   iAbsPtr;.      
2a010 63 68 61 72 20 7a 46 6c 61 67 73 5b 38 5d 3b 0a  char zFlags[8];.
2a020 0a 20 20 20 20 20 20 69 6e 66 6f 43 65 6c 6c 44  .      infoCellD
2a030 75 6d 70 28 70 44 62 2c 20 70 53 65 67 2c 20 62  ump(pDb, pSeg, b
2a040 49 6e 64 69 72 65 63 74 2c 20 70 50 67 2c 20 69  Indirect, pPg, i
2a050 43 65 6c 6c 2c 20 26 65 54 79 70 65 2c 20 26 69  Cell, &eType, &i
2a060 50 67 50 74 72 2c 0a 20 20 20 20 20 20 20 20 20  PgPtr,.         
2a070 20 26 61 4b 65 79 2c 20 26 6e 4b 65 79 2c 20 26   &aKey, &nKey, &
2a080 61 56 61 6c 2c 20 26 6e 56 61 6c 2c 20 26 62 6c  aVal, &nVal, &bl
2a090 6f 62 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20  ob.      );.    
2a0a0 20 20 69 41 62 73 50 74 72 20 3d 20 69 50 67 50    iAbsPtr = iPgP
2a0b0 74 72 20 2b 20 28 28 66 6c 61 67 73 32 20 26 20  tr + ((flags2 & 
2a0c0 53 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c  SEGMENT_BTREE_FL
2a0d0 41 47 29 20 3f 20 30 20 3a 20 69 50 74 72 29 3b  AG) ? 0 : iPtr);
2a0e0 0a 0a 20 20 20 20 20 20 6c 73 6d 46 6c 61 67 73  ..      lsmFlags
2a0f0 54 6f 53 74 72 69 6e 67 28 65 54 79 70 65 2c 20  ToString(eType, 
2a100 7a 46 6c 61 67 73 29 3b 0a 20 20 20 20 20 20 6c  zFlags);.      l
2a110 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28  smStringAppendf(
2a120 26 73 74 72 2c 20 22 25 73 20 25 64 20 28 25 73  &str, "%s %d (%s
2a130 29 20 22 2c 20 0a 20 20 20 20 20 20 20 20 20 20  ) ", .          
2a140 7a 46 6c 61 67 73 2c 20 69 41 62 73 50 74 72 2c  zFlags, iAbsPtr,
2a150 20 28 72 74 54 6f 70 69 63 28 65 54 79 70 65 29   (rtTopic(eType)
2a160 20 3f 20 22 73 79 73 22 20 3a 20 22 75 73 72 22   ? "sys" : "usr"
2a170 29 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20  ).      );.     
2a180 20 69 6e 66 6f 41 70 70 65 6e 64 42 6c 6f 62 28   infoAppendBlob(
2a190 26 73 74 72 2c 20 62 48 65 78 2c 20 61 4b 65 79  &str, bHex, aKey
2a1a0 2c 20 6e 4b 65 79 29 3b 20 0a 20 20 20 20 20 20  , nKey); .      
2a1b0 69 66 28 20 6e 56 61 6c 3e 30 20 26 26 20 62 56  if( nVal>0 && bV
2a1c0 61 6c 75 65 73 20 29 7b 0a 20 20 20 20 20 20 20  alues ){.       
2a1d0 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64   lsmStringAppend
2a1e0 66 28 26 73 74 72 2c 20 22 25 2a 73 22 2c 20 6e  f(&str, "%*s", n
2a1f0 4b 65 79 57 69 64 74 68 20 2d 20 28 6e 4b 65 79  KeyWidth - (nKey
2a200 2a 28 31 2b 62 48 65 78 29 29 2c 20 22 22 29 3b  *(1+bHex)), "");
2a210 0a 20 20 20 20 20 20 20 20 6c 73 6d 53 74 72 69  .        lsmStri
2a220 6e 67 41 70 70 65 6e 64 66 28 26 73 74 72 2c 20  ngAppendf(&str, 
2a230 22 20 22 29 3b 0a 20 20 20 20 20 20 20 20 69 6e  " ");.        in
2a240 66 6f 41 70 70 65 6e 64 42 6c 6f 62 28 26 73 74  foAppendBlob(&st
2a250 72 2c 20 62 48 65 78 2c 20 61 56 61 6c 2c 20 6e  r, bHex, aVal, n
2a260 56 61 6c 29 3b 20 0a 20 20 20 20 20 20 7d 0a 20  Val); .      }. 
2a270 20 20 20 20 20 69 66 28 20 72 74 54 6f 70 69 63       if( rtTopic
2a280 28 65 54 79 70 65 29 20 29 7b 0a 20 20 20 20 20  (eType) ){.     
2a290 20 20 20 69 6e 74 20 69 42 6c 6b 20 3d 20 28 69     int iBlk = (i
2a2a0 6e 74 29 7e 6c 73 6d 47 65 74 55 33 32 28 61 4b  nt)~lsmGetU32(aK
2a2b0 65 79 29 3b 0a 20 20 20 20 20 20 20 20 6c 73 6d  ey);.        lsm
2a2c0 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73  StringAppendf(&s
2a2d0 74 72 2c 20 22 20 20 28 62 6c 6f 63 6b 3d 25 64  tr, "  (block=%d
2a2e0 22 2c 20 69 42 6c 6b 29 3b 0a 20 20 20 20 20 20  ", iBlk);.      
2a2f0 20 20 69 66 28 20 6e 56 61 6c 3e 30 20 29 7b 0a    if( nVal>0 ){.
2a300 20 20 20 20 20 20 20 20 20 20 69 36 34 20 69 53            i64 iS
2a310 6e 61 70 20 3d 20 6c 73 6d 47 65 74 55 36 34 28  nap = lsmGetU64(
2a320 61 56 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 20  aVal);.         
2a330 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64   lsmStringAppend
2a340 66 28 26 73 74 72 2c 20 22 20 73 6e 61 70 73 68  f(&str, " snapsh
2a350 6f 74 3d 25 6c 6c 64 22 2c 20 69 53 6e 61 70 29  ot=%lld", iSnap)
2a360 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
2a370 20 20 20 20 6c 73 6d 53 74 72 69 6e 67 41 70 70      lsmStringApp
2a380 65 6e 64 66 28 26 73 74 72 2c 20 22 29 22 29 3b  endf(&str, ")");
2a390 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 6c  .      }.      l
2a3a0 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28  smStringAppendf(
2a3b0 26 73 74 72 2c 20 22 5c 6e 22 29 3b 0a 20 20 20  &str, "\n");.   
2a3c0 20 7d 0a 0a 20 20 20 20 69 66 28 20 62 44 61 74   }..    if( bDat
2a3d0 61 20 29 7b 0a 20 20 20 20 20 20 6c 73 6d 53 74  a ){.      lsmSt
2a3e0 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73 74 72  ringAppendf(&str
2a3f0 2c 20 22 5c 6e 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  , "\n-----------
2a400 2d 2d 2d 2d 2d 2d 2d 2d 22 20 0a 20 20 20 20 20  --------" .     
2a410 20 20 20 20 20 22 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d       "----------
2a420 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2a430 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2a440 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2a450 2d 2d 2d 5c 6e 22 29 3b 0a 20 20 20 20 20 20 6c  ---\n");.      l
2a460 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28  smStringAppendf(
2a470 26 73 74 72 2c 20 22 50 61 67 65 20 25 64 5c 6e  &str, "Page %d\n
2a480 22 2c 0a 20 20 20 20 20 20 20 20 20 20 69 50 67  ",.          iPg
2a490 2c 20 28 69 50 67 2d 31 29 2a 6e 44 61 74 61 2c  , (iPg-1)*nData,
2a4a0 20 69 50 67 2a 6e 44 61 74 61 20 2d 20 31 29 3b   iPg*nData - 1);
2a4b0 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  .      for(i=0; 
2a4c0 69 3c 6e 44 61 74 61 3b 20 69 20 2b 3d 20 70 65  i<nData; i += pe
2a4d0 72 4c 69 6e 65 29 7b 0a 20 20 20 20 20 20 20 20  rLine){.        
2a4e0 6c 73 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66  lsmStringAppendf
2a4f0 28 26 73 74 72 2c 20 22 25 30 34 78 3a 20 22 2c  (&str, "%04x: ",
2a500 20 69 29 3b 0a 20 20 20 20 20 20 20 20 66 6f 72   i);.        for
2a510 28 6a 3d 30 3b 20 6a 3c 70 65 72 4c 69 6e 65 3b  (j=0; j<perLine;
2a520 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20   j++){.         
2a530 20 69 66 28 20 69 2b 6a 3e 6e 44 61 74 61 20 29   if( i+j>nData )
2a540 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 73  {.            ls
2a550 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26  mStringAppendf(&
2a560 73 74 72 2c 20 22 20 20 20 22 29 3b 0a 20 20 20  str, "   ");.   
2a570 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20         }else{.  
2a580 20 20 20 20 20 20 20 20 20 20 6c 73 6d 53 74 72            lsmStr
2a590 69 6e 67 41 70 70 65 6e 64 66 28 26 73 74 72 2c  ingAppendf(&str,
2a5a0 20 22 25 30 32 78 20 22 2c 20 61 44 61 74 61 5b   "%02x ", aData[
2a5b0 69 2b 6a 5d 29 3b 0a 20 20 20 20 20 20 20 20 20  i+j]);.         
2a5c0 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   }.        }.   
2a5d0 20 20 20 20 20 6c 73 6d 53 74 72 69 6e 67 41 70       lsmStringAp
2a5e0 70 65 6e 64 66 28 26 73 74 72 2c 20 22 20 20 22  pendf(&str, "  "
2a5f0 29 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 6a  );.        for(j
2a600 3d 30 3b 20 6a 3c 70 65 72 4c 69 6e 65 3b 20 6a  =0; j<perLine; j
2a610 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  ++){.          i
2a620 66 28 20 69 2b 6a 3e 6e 44 61 74 61 20 29 7b 0a  f( i+j>nData ){.
2a630 20 20 20 20 20 20 20 20 20 20 20 20 6c 73 6d 53              lsmS
2a640 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26 73 74  tringAppendf(&st
2a650 72 2c 20 22 20 22 29 3b 0a 20 20 20 20 20 20 20  r, " ");.       
2a660 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
2a670 20 20 20 20 20 20 6c 73 6d 53 74 72 69 6e 67 41        lsmStringA
2a680 70 70 65 6e 64 66 28 26 73 74 72 2c 22 25 63 22  ppendf(&str,"%c"
2a690 2c 20 69 73 70 72 69 6e 74 28 61 44 61 74 61 5b  , isprint(aData[
2a6a0 69 2b 6a 5d 29 20 3f 20 61 44 61 74 61 5b 69 2b  i+j]) ? aData[i+
2a6b0 6a 5d 20 3a 20 27 2e 27 29 3b 0a 20 20 20 20 20  j] : '.');.     
2a6c0 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d       }.        }
2a6d0 0a 20 20 20 20 20 20 20 20 6c 73 6d 53 74 72 69  .        lsmStri
2a6e0 6e 67 41 70 70 65 6e 64 66 28 26 73 74 72 2c 22  ngAppendf(&str,"
2a6f0 5c 6e 22 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  \n");.      }.  
2a700 20 20 7d 0a 0a 20 20 20 20 2a 70 7a 4f 75 74 20    }..    *pzOut 
2a710 3d 20 73 74 72 2e 7a 3b 0a 20 20 20 20 73 6f 72  = str.z;.    sor
2a720 74 65 64 42 6c 6f 62 46 72 65 65 28 26 62 6c 6f  tedBlobFree(&blo
2a730 62 29 3b 0a 20 20 20 20 6c 73 6d 46 73 50 61 67  b);.    lsmFsPag
2a740 65 52 65 6c 65 61 73 65 28 70 50 67 29 3b 0a 20  eRelease(pPg);. 
2a750 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
2a760 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 49 6e 66 6f 50  .}..int lsmInfoP
2a770 61 67 65 44 75 6d 70 28 0a 20 20 6c 73 6d 5f 64  ageDump(.  lsm_d
2a780 62 20 2a 70 44 62 2c 20 20 20 20 20 20 20 20 20  b *pDb,         
2a790 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
2a7a0 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f  tabase handle */
2a7b0 0a 20 20 4c 73 6d 50 67 6e 6f 20 69 50 67 2c 20  .  LsmPgno iPg, 
2a7c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a7d0 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65     /* Page numbe
2a7e0 72 20 6f 66 20 70 61 67 65 20 74 6f 20 64 75 6d  r of page to dum
2a7f0 70 20 2a 2f 0a 20 20 69 6e 74 20 62 48 65 78 2c  p */.  int bHex,
2a800 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a810 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74         /* True t
2a820 6f 20 6f 75 74 70 75 74 20 6b 65 79 2f 76 61 6c  o output key/val
2a830 75 65 20 69 6e 20 68 65 78 20 66 6f 72 6d 20 2a  ue in hex form *
2a840 2f 0a 20 20 63 68 61 72 20 2a 2a 70 7a 4f 75 74  /.  char **pzOut
2a850 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a860 20 20 20 20 2f 2a 20 4f 55 54 3a 20 6c 73 6d 4d      /* OUT: lsmM
2a870 61 6c 6c 6f 63 27 64 20 73 74 72 69 6e 67 20 2a  alloc'd string *
2a880 2f 0a 29 7b 0a 20 20 69 6e 74 20 66 6c 61 67 73  /.){.  int flags
2a890 20 3d 20 49 4e 46 4f 5f 50 41 47 45 5f 44 55 4d   = INFO_PAGE_DUM
2a8a0 50 5f 44 41 54 41 20 7c 20 49 4e 46 4f 5f 50 41  P_DATA | INFO_PA
2a8b0 47 45 5f 44 55 4d 50 5f 56 41 4c 55 45 53 3b 0a  GE_DUMP_VALUES;.
2a8c0 20 20 69 66 28 20 62 48 65 78 20 29 20 66 6c 61    if( bHex ) fla
2a8d0 67 73 20 7c 3d 20 49 4e 46 4f 5f 50 41 47 45 5f  gs |= INFO_PAGE_
2a8e0 44 55 4d 50 5f 48 45 58 3b 0a 20 20 72 65 74 75  DUMP_HEX;.  retu
2a8f0 72 6e 20 69 6e 66 6f 50 61 67 65 44 75 6d 70 28  rn infoPageDump(
2a900 70 44 62 2c 20 69 50 67 2c 20 66 6c 61 67 73 2c  pDb, iPg, flags,
2a910 20 70 7a 4f 75 74 29 3b 0a 7d 0a 0a 76 6f 69 64   pzOut);.}..void
2a920 20 73 6f 72 74 65 64 44 75 6d 70 53 65 67 6d 65   sortedDumpSegme
2a930 6e 74 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20  nt(lsm_db *pDb, 
2a940 53 65 67 6d 65 6e 74 20 2a 70 52 75 6e 2c 20 69  Segment *pRun, i
2a950 6e 74 20 62 56 61 6c 73 29 7b 0a 20 20 61 73 73  nt bVals){.  ass
2a960 65 72 74 28 20 70 44 62 2d 3e 78 4c 6f 67 20 29  ert( pDb->xLog )
2a970 3b 0a 20 20 69 66 28 20 70 52 75 6e 20 26 26 20  ;.  if( pRun && 
2a980 70 52 75 6e 2d 3e 69 46 69 72 73 74 20 29 7b 0a  pRun->iFirst ){.
2a990 20 20 20 20 69 6e 74 20 66 6c 61 67 73 20 3d 20      int flags = 
2a9a0 28 62 56 61 6c 73 20 3f 20 49 4e 46 4f 5f 50 41  (bVals ? INFO_PA
2a9b0 47 45 5f 44 55 4d 50 5f 56 41 4c 55 45 53 20 3a  GE_DUMP_VALUES :
2a9c0 20 30 29 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a   0);.    char *z
2a9d0 53 65 67 3b 0a 20 20 20 20 50 61 67 65 20 2a 70  Seg;.    Page *p
2a9e0 50 67 3b 0a 0a 20 20 20 20 7a 53 65 67 20 3d 20  Pg;..    zSeg = 
2a9f0 73 65 67 54 6f 53 74 72 69 6e 67 28 70 44 62 2d  segToString(pDb-
2aa00 3e 70 45 6e 76 2c 20 70 52 75 6e 2c 20 30 29 3b  >pEnv, pRun, 0);
2aa10 0a 20 20 20 20 6c 73 6d 4c 6f 67 4d 65 73 73 61  .    lsmLogMessa
2aa20 67 65 28 70 44 62 2c 20 4c 53 4d 5f 4f 4b 2c 20  ge(pDb, LSM_OK, 
2aa30 22 53 65 67 6d 65 6e 74 3a 20 25 73 22 2c 20 7a  "Segment: %s", z
2aa40 53 65 67 29 3b 0a 20 20 20 20 6c 73 6d 46 72 65  Seg);.    lsmFre
2aa50 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 7a 53 65  e(pDb->pEnv, zSe
2aa60 67 29 3b 0a 0a 20 20 20 20 6c 73 6d 46 73 44 62  g);..    lsmFsDb
2aa70 50 61 67 65 47 65 74 28 70 44 62 2d 3e 70 46 53  PageGet(pDb->pFS
2aa80 2c 20 70 52 75 6e 2c 20 70 52 75 6e 2d 3e 69 46  , pRun, pRun->iF
2aa90 69 72 73 74 2c 20 26 70 50 67 29 3b 0a 20 20 20  irst, &pPg);.   
2aaa0 20 77 68 69 6c 65 28 20 70 50 67 20 29 7b 0a 20   while( pPg ){. 
2aab0 20 20 20 20 20 50 61 67 65 20 2a 70 4e 65 78 74       Page *pNext
2aac0 3b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 20  ;.      char *z 
2aad0 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 66 6f 50  = 0;.      infoP
2aae0 61 67 65 44 75 6d 70 28 70 44 62 2c 20 6c 73 6d  ageDump(pDb, lsm
2aaf0 46 73 50 61 67 65 4e 75 6d 62 65 72 28 70 50 67  FsPageNumber(pPg
2ab00 29 2c 20 66 6c 61 67 73 2c 20 26 7a 29 3b 0a 20  ), flags, &z);. 
2ab10 20 20 20 20 20 6c 73 6d 4c 6f 67 4d 65 73 73 61       lsmLogMessa
2ab20 67 65 28 70 44 62 2c 20 4c 53 4d 5f 4f 4b 2c 20  ge(pDb, LSM_OK, 
2ab30 22 25 73 22 2c 20 7a 29 3b 0a 20 20 20 20 20 20  "%s", z);.      
2ab40 6c 73 6d 46 72 65 65 28 70 44 62 2d 3e 70 45 6e  lsmFree(pDb->pEn
2ab50 76 2c 20 7a 29 3b 0a 23 69 66 20 30 0a 20 20 20  v, z);.#if 0.   
2ab60 20 20 20 73 6f 72 74 65 64 44 75 6d 70 50 61 67     sortedDumpPag
2ab70 65 28 70 44 62 2c 20 70 52 75 6e 2c 20 70 50 67  e(pDb, pRun, pPg
2ab80 2c 20 62 56 61 6c 73 29 3b 0a 23 65 6e 64 69 66  , bVals);.#endif
2ab90 0a 20 20 20 20 20 20 6c 73 6d 46 73 44 62 50 61  .      lsmFsDbPa
2aba0 67 65 4e 65 78 74 28 70 52 75 6e 2c 20 70 50 67  geNext(pRun, pPg
2abb0 2c 20 31 2c 20 26 70 4e 65 78 74 29 3b 0a 20 20  , 1, &pNext);.  
2abc0 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c      lsmFsPageRel
2abd0 65 61 73 65 28 70 50 67 29 3b 0a 20 20 20 20 20  ease(pPg);.     
2abe0 20 70 50 67 20 3d 20 70 4e 65 78 74 3b 0a 20 20   pPg = pNext;.  
2abf0 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a    }.  }.}../*.**
2ac00 20 49 6e 76 6f 6b 65 20 74 68 65 20 6c 6f 67 20   Invoke the log 
2ac10 63 61 6c 6c 62 61 63 6b 20 7a 65 72 6f 20 6f 72  callback zero or
2ac20 20 6d 6f 72 65 20 74 69 6d 65 73 20 77 69 74 68   more times with
2ac30 20 6d 65 73 73 61 67 65 73 20 74 68 61 74 20 64   messages that d
2ac40 65 73 63 72 69 62 65 0a 2a 2a 20 74 68 65 20 63  escribe.** the c
2ac50 75 72 72 65 6e 74 20 64 61 74 61 62 61 73 65 20  urrent database 
2ac60 73 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 76 6f  structure..*/.vo
2ac70 69 64 20 6c 73 6d 53 6f 72 74 65 64 44 75 6d 70  id lsmSortedDump
2ac80 53 74 72 75 63 74 75 72 65 28 0a 20 20 6c 73 6d  Structure(.  lsm
2ac90 5f 64 62 20 2a 70 44 62 2c 20 20 20 20 20 20 20  _db *pDb,       
2aca0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2acb0 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20  Database handle 
2acc0 28 75 73 65 64 20 66 6f 72 20 78 4c 6f 67 20 63  (used for xLog c
2acd0 61 6c 6c 62 61 63 6b 29 20 2a 2f 0a 20 20 53 6e  allback) */.  Sn
2ace0 61 70 73 68 6f 74 20 2a 70 53 6e 61 70 2c 20 20  apshot *pSnap,  
2acf0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2ad00 20 53 6e 61 70 73 68 6f 74 20 74 6f 20 64 75 6d   Snapshot to dum
2ad10 70 20 2a 2f 0a 20 20 69 6e 74 20 62 4b 65 79 73  p */.  int bKeys
2ad20 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2ad30 20 20 20 20 20 20 20 2f 2a 20 4f 75 74 70 75 74         /* Output
2ad40 20 74 68 65 20 6b 65 79 73 20 66 72 6f 6d 20 65   the keys from e
2ad50 61 63 68 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 20  ach segment */. 
2ad60 20 69 6e 74 20 62 56 61 6c 73 2c 20 20 20 20 20   int bVals,     
2ad70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ad80 20 2f 2a 20 4f 75 74 70 75 74 20 74 68 65 20 76   /* Output the v
2ad90 61 6c 75 65 73 20 66 72 6f 6d 20 65 61 63 68 20  alues from each 
2ada0 73 65 67 6d 65 6e 74 20 2a 2f 0a 20 20 63 6f 6e  segment */.  con
2adb0 73 74 20 63 68 61 72 20 2a 7a 57 68 79 20 20 20  st char *zWhy   
2adc0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2add0 43 61 70 74 69 6f 6e 20 74 6f 20 70 72 69 6e 74  Caption to print
2ade0 20 6e 65 61 72 20 74 6f 70 20 6f 66 20 64 75 6d   near top of dum
2adf0 70 20 2a 2f 0a 29 7b 0a 20 20 53 6e 61 70 73 68  p */.){.  Snapsh
2ae00 6f 74 20 2a 70 44 75 6d 70 20 3d 20 70 53 6e 61  ot *pDump = pSna
2ae10 70 3b 0a 20 20 4c 65 76 65 6c 20 2a 70 54 6f 70  p;.  Level *pTop
2ae20 4c 65 76 65 6c 3b 0a 20 20 63 68 61 72 20 2a 7a  Level;.  char *z
2ae30 46 72 65 65 20 3d 20 30 3b 0a 0a 20 20 61 73 73  Free = 0;..  ass
2ae40 65 72 74 28 20 70 53 6e 61 70 20 29 3b 0a 20 20  ert( pSnap );.  
2ae50 70 54 6f 70 4c 65 76 65 6c 20 3d 20 6c 73 6d 44  pTopLevel = lsmD
2ae60 62 53 6e 61 70 73 68 6f 74 4c 65 76 65 6c 28 70  bSnapshotLevel(p
2ae70 44 75 6d 70 29 3b 0a 20 20 69 66 28 20 70 44 62  Dump);.  if( pDb
2ae80 2d 3e 78 4c 6f 67 20 26 26 20 70 54 6f 70 4c 65  ->xLog && pTopLe
2ae90 76 65 6c 20 29 7b 0a 20 20 20 20 73 74 61 74 69  vel ){.    stati
2aea0 63 20 69 6e 74 20 6e 43 61 6c 6c 20 3d 20 30 3b  c int nCall = 0;
2aeb0 0a 20 20 20 20 4c 65 76 65 6c 20 2a 70 4c 65 76  .    Level *pLev
2aec0 65 6c 3b 0a 20 20 20 20 69 6e 74 20 69 4c 65 76  el;.    int iLev
2aed0 65 6c 20 3d 20 30 3b 0a 0a 20 20 20 20 6e 43 61  el = 0;..    nCa
2aee0 6c 6c 2b 2b 3b 0a 20 20 20 20 6c 73 6d 4c 6f 67  ll++;.    lsmLog
2aef0 4d 65 73 73 61 67 65 28 70 44 62 2c 20 4c 53 4d  Message(pDb, LSM
2af00 5f 4f 4b 2c 20 22 44 61 74 61 62 61 73 65 20 73  _OK, "Database s
2af10 74 72 75 63 74 75 72 65 20 25 64 20 28 25 73 29  tructure %d (%s)
2af20 22 2c 20 6e 43 61 6c 6c 2c 20 7a 57 68 79 29 3b  ", nCall, zWhy);
2af30 0a 0a 23 69 66 20 30 0a 20 20 20 20 69 66 28 20  ..#if 0.    if( 
2af40 6e 43 61 6c 6c 3d 3d 31 30 33 31 20 7c 7c 20 6e  nCall==1031 || n
2af50 43 61 6c 6c 3d 3d 31 30 33 32 20 29 20 62 4b 65  Call==1032 ) bKe
2af60 79 73 3d 31 3b 0a 23 65 6e 64 69 66 0a 0a 20 20  ys=1;.#endif..  
2af70 20 20 66 6f 72 28 70 4c 65 76 65 6c 3d 70 54 6f    for(pLevel=pTo
2af80 70 4c 65 76 65 6c 3b 20 70 4c 65 76 65 6c 3b 20  pLevel; pLevel; 
2af90 70 4c 65 76 65 6c 3d 70 4c 65 76 65 6c 2d 3e 70  pLevel=pLevel->p
2afa0 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 63 68 61  Next){.      cha
2afb0 72 20 7a 4c 65 66 74 5b 31 30 32 34 5d 3b 0a 20  r zLeft[1024];. 
2afc0 20 20 20 20 20 63 68 61 72 20 7a 52 69 67 68 74       char zRight
2afd0 5b 31 30 32 34 5d 3b 0a 20 20 20 20 20 20 69 6e  [1024];.      in
2afe0 74 20 69 20 3d 20 30 3b 0a 0a 20 20 20 20 20 20  t i = 0;..      
2aff0 53 65 67 6d 65 6e 74 20 2a 61 4c 65 66 74 5b 32  Segment *aLeft[2
2b000 34 5d 3b 20 20 0a 20 20 20 20 20 20 53 65 67 6d  4];  .      Segm
2b010 65 6e 74 20 2a 61 52 69 67 68 74 5b 32 34 5d 3b  ent *aRight[24];
2b020 0a 0a 20 20 20 20 20 20 69 6e 74 20 6e 4c 65 66  ..      int nLef
2b030 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 74  t = 0;.      int
2b040 20 6e 52 69 67 68 74 20 3d 20 30 3b 0a 0a 20 20   nRight = 0;..  
2b050 20 20 20 20 53 65 67 6d 65 6e 74 20 2a 70 53 65      Segment *pSe
2b060 67 20 3d 20 26 70 4c 65 76 65 6c 2d 3e 6c 68 73  g = &pLevel->lhs
2b070 3b 0a 20 20 20 20 20 20 61 4c 65 66 74 5b 6e 4c  ;.      aLeft[nL
2b080 65 66 74 2b 2b 5d 20 3d 20 70 53 65 67 3b 0a 0a  eft++] = pSeg;..
2b090 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69        for(i=0; i
2b0a0 3c 70 4c 65 76 65 6c 2d 3e 6e 52 69 67 68 74 3b  <pLevel->nRight;
2b0b0 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 61   i++){.        a
2b0c0 52 69 67 68 74 5b 6e 52 69 67 68 74 2b 2b 5d 20  Right[nRight++] 
2b0d0 3d 20 26 70 4c 65 76 65 6c 2d 3e 61 52 68 73 5b  = &pLevel->aRhs[
2b0e0 69 5d 3b 0a 20 20 20 20 20 20 7d 0a 0a 23 69 66  i];.      }..#if
2b0f0 64 65 66 20 4c 53 4d 5f 4c 4f 47 5f 46 52 45 45  def LSM_LOG_FREE
2b100 4c 49 53 54 0a 20 20 20 20 20 20 69 66 28 20 6e  LIST.      if( n
2b110 52 69 67 68 74 20 29 7b 0a 20 20 20 20 20 20 20  Right ){.       
2b120 20 6d 65 6d 6d 6f 76 65 28 26 61 52 69 67 68 74   memmove(&aRight
2b130 5b 31 5d 2c 20 61 52 69 67 68 74 2c 20 73 69 7a  [1], aRight, siz
2b140 65 6f 66 28 61 52 69 67 68 74 5b 30 5d 29 2a 6e  eof(aRight[0])*n
2b150 52 69 67 68 74 29 3b 0a 20 20 20 20 20 20 20 20  Right);.        
2b160 61 52 69 67 68 74 5b 30 5d 20 3d 20 30 3b 0a 20  aRight[0] = 0;. 
2b170 20 20 20 20 20 20 20 6e 52 69 67 68 74 2b 2b 3b         nRight++;
2b180 0a 20 20 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a  .      }.#endif.
2b190 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  .      for(i=0; 
2b1a0 69 3c 6e 4c 65 66 74 20 7c 7c 20 69 3c 6e 52 69  i<nLeft || i<nRi
2b1b0 67 68 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  ght; i++){.     
2b1c0 20 20 20 69 6e 74 20 69 50 61 64 20 3d 20 30 3b     int iPad = 0;
2b1d0 0a 20 20 20 20 20 20 20 20 63 68 61 72 20 7a 4c  .        char zL
2b1e0 65 76 65 6c 5b 33 32 5d 3b 0a 20 20 20 20 20 20  evel[32];.      
2b1f0 20 20 7a 4c 65 66 74 5b 30 5d 20 3d 20 27 5c 30    zLeft[0] = '\0
2b200 27 3b 0a 20 20 20 20 20 20 20 20 7a 52 69 67 68  ';.        zRigh
2b210 74 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 0a 20 20  t[0] = '\0';..  
2b220 20 20 20 20 20 20 69 66 28 20 69 3c 6e 4c 65 66        if( i<nLef
2b230 74 20 29 7b 20 0a 20 20 20 20 20 20 20 20 20 20  t ){ .          
2b240 66 69 6c 65 54 6f 53 74 72 69 6e 67 28 70 44 62  fileToString(pDb
2b250 2c 20 7a 4c 65 66 74 2c 20 73 69 7a 65 6f 66 28  , zLeft, sizeof(
2b260 7a 4c 65 66 74 29 2c 20 32 34 2c 20 61 4c 65 66  zLeft), 24, aLef
2b270 74 5b 69 5d 29 3b 20 0a 20 20 20 20 20 20 20 20  t[i]); .        
2b280 7d 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 3c  }.        if( i<
2b290 6e 52 69 67 68 74 20 29 7b 20 0a 20 20 20 20 20  nRight ){ .     
2b2a0 20 20 20 20 20 66 69 6c 65 54 6f 53 74 72 69 6e       fileToStrin
2b2b0 67 28 70 44 62 2c 20 7a 52 69 67 68 74 2c 20 73  g(pDb, zRight, s
2b2c0 69 7a 65 6f 66 28 7a 52 69 67 68 74 29 2c 20 32  izeof(zRight), 2
2b2d0 34 2c 20 61 52 69 67 68 74 5b 69 5d 29 3b 20 0a  4, aRight[i]); .
2b2e0 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
2b2f0 20 20 20 69 66 28 20 69 3d 3d 30 20 29 7b 0a 20     if( i==0 ){. 
2b300 20 20 20 20 20 20 20 20 20 73 6e 70 72 69 6e 74           snprint
2b310 66 28 7a 4c 65 76 65 6c 2c 20 73 69 7a 65 6f 66  f(zLevel, sizeof
2b320 28 7a 4c 65 76 65 6c 29 2c 20 22 4c 25 64 3a 20  (zLevel), "L%d: 
2b330 28 61 67 65 3d 25 64 29 20 28 66 6c 61 67 73 3d  (age=%d) (flags=
2b340 25 2e 34 78 29 22 2c 0a 20 20 20 20 20 20 20 20  %.4x)",.        
2b350 20 20 20 20 20 20 69 4c 65 76 65 6c 2c 20 28 69        iLevel, (i
2b360 6e 74 29 70 4c 65 76 65 6c 2d 3e 69 41 67 65 2c  nt)pLevel->iAge,
2b370 20 28 69 6e 74 29 70 4c 65 76 65 6c 2d 3e 66 6c   (int)pLevel->fl
2b380 61 67 73 0a 20 20 20 20 20 20 20 20 20 20 29 3b  ags.          );
2b390 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  .        }else{.
2b3a0 20 20 20 20 20 20 20 20 20 20 7a 4c 65 76 65 6c            zLevel
2b3b0 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 20 20  [0] = '\0';.    
2b3c0 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 69      }..        i
2b3d0 66 28 20 6e 52 69 67 68 74 3d 3d 30 20 29 7b 0a  f( nRight==0 ){.
2b3e0 20 20 20 20 20 20 20 20 20 20 69 50 61 64 20 3d            iPad =
2b3f0 20 31 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a   10;.        }..
2b400 20 20 20 20 20 20 20 20 6c 73 6d 4c 6f 67 4d 65          lsmLogMe
2b410 73 73 61 67 65 28 70 44 62 2c 20 4c 53 4d 5f 4f  ssage(pDb, LSM_O
2b420 4b 2c 20 22 25 20 32 35 73 20 25 20 2a 73 25 20  K, "% 25s % *s% 
2b430 2d 33 35 73 20 25 73 22 2c 20 0a 20 20 20 20 20  -35s %s", .     
2b440 20 20 20 20 20 20 20 7a 4c 65 76 65 6c 2c 20 69         zLevel, i
2b450 50 61 64 2c 20 22 22 2c 20 7a 4c 65 66 74 2c 20  Pad, "", zLeft, 
2b460 7a 52 69 67 68 74 0a 20 20 20 20 20 20 20 20 29  zRight.        )
2b470 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  ;.      }..     
2b480 20 69 4c 65 76 65 6c 2b 2b 3b 0a 20 20 20 20 7d   iLevel++;.    }
2b490 0a 0a 20 20 20 20 69 66 28 20 62 4b 65 79 73 20  ..    if( bKeys 
2b4a0 29 7b 0a 20 20 20 20 20 20 66 6f 72 28 70 4c 65  ){.      for(pLe
2b4b0 76 65 6c 3d 70 54 6f 70 4c 65 76 65 6c 3b 20 70  vel=pTopLevel; p
2b4c0 4c 65 76 65 6c 3b 20 70 4c 65 76 65 6c 3d 70 4c  Level; pLevel=pL
2b4d0 65 76 65 6c 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  evel->pNext){.  
2b4e0 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20        int i;.   
2b4f0 20 20 20 20 20 73 6f 72 74 65 64 44 75 6d 70 53       sortedDumpS
2b500 65 67 6d 65 6e 74 28 70 44 62 2c 20 26 70 4c 65  egment(pDb, &pLe
2b510 76 65 6c 2d 3e 6c 68 73 2c 20 62 56 61 6c 73 29  vel->lhs, bVals)
2b520 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d  ;.        for(i=
2b530 30 3b 20 69 3c 70 4c 65 76 65 6c 2d 3e 6e 52 69  0; i<pLevel->nRi
2b540 67 68 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  ght; i++){.     
2b550 20 20 20 20 20 73 6f 72 74 65 64 44 75 6d 70 53       sortedDumpS
2b560 65 67 6d 65 6e 74 28 70 44 62 2c 20 26 70 4c 65  egment(pDb, &pLe
2b570 76 65 6c 2d 3e 61 52 68 73 5b 69 5d 2c 20 62 56  vel->aRhs[i], bV
2b580 61 6c 73 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  als);.        }.
2b590 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
2b5a0 7d 0a 0a 20 20 6c 73 6d 49 6e 66 6f 46 72 65 65  }..  lsmInfoFree
2b5b0 6c 69 73 74 28 70 44 62 2c 20 26 7a 46 72 65 65  list(pDb, &zFree
2b5c0 29 3b 0a 20 20 6c 73 6d 4c 6f 67 4d 65 73 73 61  );.  lsmLogMessa
2b5d0 67 65 28 70 44 62 2c 20 4c 53 4d 5f 4f 4b 2c 20  ge(pDb, LSM_OK, 
2b5e0 22 46 72 65 65 6c 69 73 74 3a 20 25 73 22 2c 20  "Freelist: %s", 
2b5f0 7a 46 72 65 65 29 3b 0a 20 20 6c 73 6d 46 72 65  zFree);.  lsmFre
2b600 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 7a 46 72  e(pDb->pEnv, zFr
2b610 65 65 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  ee);..  assert( 
2b620 6c 73 6d 46 73 49 6e 74 65 67 72 69 74 79 43 68  lsmFsIntegrityCh
2b630 65 63 6b 28 70 44 62 29 20 29 3b 0a 7d 0a 0a 76  eck(pDb) );.}..v
2b640 6f 69 64 20 6c 73 6d 53 6f 72 74 65 64 46 72 65  oid lsmSortedFre
2b650 65 4c 65 76 65 6c 28 6c 73 6d 5f 65 6e 76 20 2a  eLevel(lsm_env *
2b660 70 45 6e 76 2c 20 4c 65 76 65 6c 20 2a 70 4c 65  pEnv, Level *pLe
2b670 76 65 6c 29 7b 0a 20 20 4c 65 76 65 6c 20 2a 70  vel){.  Level *p
2b680 4e 65 78 74 3b 0a 20 20 4c 65 76 65 6c 20 2a 70  Next;.  Level *p
2b690 3b 0a 0a 20 20 66 6f 72 28 70 3d 70 4c 65 76 65  ;..  for(p=pLeve
2b6a0 6c 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a  l; p; p=pNext){.
2b6b0 20 20 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 70      pNext = p->p
2b6c0 4e 65 78 74 3b 0a 20 20 20 20 73 6f 72 74 65 64  Next;.    sorted
2b6d0 46 72 65 65 4c 65 76 65 6c 28 70 45 6e 76 2c 20  FreeLevel(pEnv, 
2b6e0 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 76 6f 69 64 20  p);.  }.}..void 
2b6f0 6c 73 6d 53 6f 72 74 65 64 53 61 76 65 54 72 65  lsmSortedSaveTre
2b700 65 43 75 72 73 6f 72 73 28 6c 73 6d 5f 64 62 20  eCursors(lsm_db 
2b710 2a 70 44 62 29 7b 0a 20 20 4d 75 6c 74 69 43 75  *pDb){.  MultiCu
2b720 72 73 6f 72 20 2a 70 43 73 72 3b 0a 20 20 66 6f  rsor *pCsr;.  fo
2b730 72 28 70 43 73 72 3d 70 44 62 2d 3e 70 43 73 72  r(pCsr=pDb->pCsr
2b740 3b 20 70 43 73 72 3b 20 70 43 73 72 3d 70 43 73  ; pCsr; pCsr=pCs
2b750 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 6c  r->pNext){.    l
2b760 73 6d 54 72 65 65 43 75 72 73 6f 72 53 61 76 65  smTreeCursorSave
2b770 28 70 43 73 72 2d 3e 61 70 54 72 65 65 43 73 72  (pCsr->apTreeCsr
2b780 5b 30 5d 29 3b 0a 20 20 20 20 6c 73 6d 54 72 65  [0]);.    lsmTre
2b790 65 43 75 72 73 6f 72 53 61 76 65 28 70 43 73 72  eCursorSave(pCsr
2b7a0 2d 3e 61 70 54 72 65 65 43 73 72 5b 31 5d 29 3b  ->apTreeCsr[1]);
2b7b0 0a 20 20 7d 0a 7d 0a 0a 76 6f 69 64 20 6c 73 6d  .  }.}..void lsm
2b7c0 53 6f 72 74 65 64 45 78 70 61 6e 64 42 74 72 65  SortedExpandBtre
2b7d0 65 50 61 67 65 28 50 61 67 65 20 2a 70 50 67 2c  ePage(Page *pPg,
2b7e0 20 69 6e 74 20 6e 4f 72 69 67 29 7b 0a 20 20 75   int nOrig){.  u
2b7f0 38 20 2a 61 44 61 74 61 3b 0a 20 20 69 6e 74 20  8 *aData;.  int 
2b800 6e 44 61 74 61 3b 0a 20 20 69 6e 74 20 6e 45 6e  nData;.  int nEn
2b810 74 72 79 3b 0a 20 20 69 6e 74 20 69 48 64 72 3b  try;.  int iHdr;
2b820 0a 0a 20 20 61 44 61 74 61 20 3d 20 6c 73 6d 46  ..  aData = lsmF
2b830 73 50 61 67 65 44 61 74 61 28 70 50 67 2c 20 26  sPageData(pPg, &
2b840 6e 44 61 74 61 29 3b 0a 20 20 6e 45 6e 74 72 79  nData);.  nEntry
2b850 20 3d 20 70 61 67 65 47 65 74 4e 52 65 63 28 61   = pageGetNRec(a
2b860 44 61 74 61 2c 20 6e 4f 72 69 67 29 3b 0a 20 20  Data, nOrig);.  
2b870 69 48 64 72 20 3d 20 53 45 47 4d 45 4e 54 5f 45  iHdr = SEGMENT_E
2b880 4f 46 28 6e 4f 72 69 67 2c 20 6e 45 6e 74 72 79  OF(nOrig, nEntry
2b890 29 3b 0a 20 20 6d 65 6d 6d 6f 76 65 28 26 61 44  );.  memmove(&aD
2b8a0 61 74 61 5b 69 48 64 72 20 2b 20 28 6e 44 61 74  ata[iHdr + (nDat
2b8b0 61 2d 6e 4f 72 69 67 29 5d 2c 20 26 61 44 61 74  a-nOrig)], &aDat
2b8c0 61 5b 69 48 64 72 5d 2c 20 6e 4f 72 69 67 2d 69  a[iHdr], nOrig-i
2b8d0 48 64 72 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20  Hdr);.}..#ifdef 
2b8e0 4c 53 4d 5f 44 45 42 55 47 5f 45 58 50 45 4e 53  LSM_DEBUG_EXPENS
2b8f0 49 56 45 0a 73 74 61 74 69 63 20 76 6f 69 64 20  IVE.static void 
2b900 61 73 73 65 72 74 52 75 6e 49 6e 4f 72 64 65 72  assertRunInOrder
2b910 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 53 65  (lsm_db *pDb, Se
2b920 67 6d 65 6e 74 20 2a 70 53 65 67 29 7b 0a 20 20  gment *pSeg){.  
2b930 50 61 67 65 20 2a 70 50 67 20 3d 20 30 3b 0a 20  Page *pPg = 0;. 
2b940 20 4c 73 6d 42 6c 6f 62 20 62 6c 6f 62 31 20 3d   LsmBlob blob1 =
2b950 20 7b 30 2c 20 30 2c 20 30 2c 20 30 7d 3b 0a 20   {0, 0, 0, 0};. 
2b960 20 4c 73 6d 42 6c 6f 62 20 62 6c 6f 62 32 20 3d   LsmBlob blob2 =
2b970 20 7b 30 2c 20 30 2c 20 30 2c 20 30 7d 3b 0a 0a   {0, 0, 0, 0};..
2b980 20 20 6c 73 6d 46 73 44 62 50 61 67 65 47 65 74    lsmFsDbPageGet
2b990 28 70 44 62 2d 3e 70 46 53 2c 20 70 53 65 67 2c  (pDb->pFS, pSeg,
2b9a0 20 70 53 65 67 2d 3e 69 46 69 72 73 74 2c 20 26   pSeg->iFirst, &
2b9b0 70 50 67 29 3b 0a 20 20 77 68 69 6c 65 28 20 70  pPg);.  while( p
2b9c0 50 67 20 29 7b 0a 20 20 20 20 75 38 20 2a 61 44  Pg ){.    u8 *aD
2b9d0 61 74 61 3b 20 69 6e 74 20 6e 44 61 74 61 3b 0a  ata; int nData;.
2b9e0 20 20 20 20 50 61 67 65 20 2a 70 4e 65 78 74 3b      Page *pNext;
2b9f0 0a 0a 20 20 20 20 61 44 61 74 61 20 3d 20 6c 73  ..    aData = ls
2ba00 6d 46 73 50 61 67 65 44 61 74 61 28 70 50 67 2c  mFsPageData(pPg,
2ba10 20 26 6e 44 61 74 61 29 3b 0a 20 20 20 20 69 66   &nData);.    if
2ba20 28 20 30 3d 3d 28 70 61 67 65 47 65 74 46 6c 61  ( 0==(pageGetFla
2ba30 67 73 28 61 44 61 74 61 2c 20 6e 44 61 74 61 29  gs(aData, nData)
2ba40 20 26 20 53 45 47 4d 45 4e 54 5f 42 54 52 45 45   & SEGMENT_BTREE
2ba50 5f 46 4c 41 47 29 20 29 7b 0a 20 20 20 20 20 20  _FLAG) ){.      
2ba60 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 69 6e 74  int i;.      int
2ba70 20 6e 52 65 63 20 3d 20 70 61 67 65 47 65 74 4e   nRec = pageGetN
2ba80 52 65 63 28 61 44 61 74 61 2c 20 6e 44 61 74 61  Rec(aData, nData
2ba90 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30  );.      for(i=0
2baa0 3b 20 69 3c 6e 52 65 63 3b 20 69 2b 2b 29 7b 0a  ; i<nRec; i++){.
2bab0 20 20 20 20 20 20 20 20 69 6e 74 20 69 54 6f 70          int iTop
2bac0 69 63 31 2c 20 69 54 6f 70 69 63 32 3b 0a 20 20  ic1, iTopic2;.  
2bad0 20 20 20 20 20 20 70 61 67 65 47 65 74 4b 65 79        pageGetKey
2bae0 43 6f 70 79 28 70 44 62 2d 3e 70 45 6e 76 2c 20  Copy(pDb->pEnv, 
2baf0 70 53 65 67 2c 20 70 50 67 2c 20 69 2c 20 26 69  pSeg, pPg, i, &i
2bb00 54 6f 70 69 63 31 2c 20 26 62 6c 6f 62 31 29 3b  Topic1, &blob1);
2bb10 0a 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 3d  ..        if( i=
2bb20 3d 30 20 26 26 20 62 6c 6f 62 32 2e 6e 44 61 74  =0 && blob2.nDat
2bb30 61 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 61  a ){.          a
2bb40 73 73 65 72 74 28 20 73 6f 72 74 65 64 4b 65 79  ssert( sortedKey
2bb50 43 6f 6d 70 61 72 65 28 0a 20 20 20 20 20 20 20  Compare(.       
2bb60 20 20 20 20 20 20 20 20 20 70 44 62 2d 3e 78 43           pDb->xC
2bb70 6d 70 2c 20 69 54 6f 70 69 63 32 2c 20 62 6c 6f  mp, iTopic2, blo
2bb80 62 32 2e 70 44 61 74 61 2c 20 62 6c 6f 62 32 2e  b2.pData, blob2.
2bb90 6e 44 61 74 61 2c 0a 20 20 20 20 20 20 20 20 20  nData,.         
2bba0 20 20 20 20 20 20 20 69 54 6f 70 69 63 31 2c 20         iTopic1, 
2bbb0 62 6c 6f 62 31 2e 70 44 61 74 61 2c 20 62 6c 6f  blob1.pData, blo
2bbc0 62 31 2e 6e 44 61 74 61 0a 20 20 20 20 20 20 20  b1.nData.       
2bbd0 20 20 20 29 3c 30 20 29 3b 0a 20 20 20 20 20 20     )<0 );.      
2bbe0 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 69 66 28    }..        if(
2bbf0 20 69 3c 28 6e 52 65 63 2d 31 29 20 29 7b 0a 20   i<(nRec-1) ){. 
2bc00 20 20 20 20 20 20 20 20 20 70 61 67 65 47 65 74           pageGet
2bc10 4b 65 79 43 6f 70 79 28 70 44 62 2d 3e 70 45 6e  KeyCopy(pDb->pEn
2bc20 76 2c 20 70 53 65 67 2c 20 70 50 67 2c 20 69 2b  v, pSeg, pPg, i+
2bc30 31 2c 20 26 69 54 6f 70 69 63 32 2c 20 26 62 6c  1, &iTopic2, &bl
2bc40 6f 62 32 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ob2);.          
2bc50 61 73 73 65 72 74 28 20 73 6f 72 74 65 64 4b 65  assert( sortedKe
2bc60 79 43 6f 6d 70 61 72 65 28 0a 20 20 20 20 20 20  yCompare(.      
2bc70 20 20 20 20 20 20 20 20 20 20 70 44 62 2d 3e 78            pDb->x
2bc80 43 6d 70 2c 20 69 54 6f 70 69 63 31 2c 20 62 6c  Cmp, iTopic1, bl
2bc90 6f 62 31 2e 70 44 61 74 61 2c 20 62 6c 6f 62 31  ob1.pData, blob1
2bca0 2e 6e 44 61 74 61 2c 0a 20 20 20 20 20 20 20 20  .nData,.        
2bcb0 20 20 20 20 20 20 20 20 69 54 6f 70 69 63 32 2c          iTopic2,
2bcc0 20 62 6c 6f 62 32 2e 70 44 61 74 61 2c 20 62 6c   blob2.pData, bl
2bcd0 6f 62 32 2e 6e 44 61 74 61 0a 20 20 20 20 20 20  ob2.nData.      
2bce0 20 20 20 20 29 3c 30 20 29 3b 0a 20 20 20 20 20      )<0 );.     
2bcf0 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
2bd00 20 7d 0a 0a 20 20 20 20 6c 73 6d 46 73 44 62 50   }..    lsmFsDbP
2bd10 61 67 65 4e 65 78 74 28 70 53 65 67 2c 20 70 50  ageNext(pSeg, pP
2bd20 67 2c 20 31 2c 20 26 70 4e 65 78 74 29 3b 0a 20  g, 1, &pNext);. 
2bd30 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65     lsmFsPageRele
2bd40 61 73 65 28 70 50 67 29 3b 0a 20 20 20 20 70 50  ase(pPg);.    pP
2bd50 67 20 3d 20 70 4e 65 78 74 3b 0a 20 20 7d 0a 0a  g = pNext;.  }..
2bd60 20 20 73 6f 72 74 65 64 42 6c 6f 62 46 72 65 65    sortedBlobFree
2bd70 28 26 62 6c 6f 62 31 29 3b 0a 20 20 73 6f 72 74  (&blob1);.  sort
2bd80 65 64 42 6c 6f 62 46 72 65 65 28 26 62 6c 6f 62  edBlobFree(&blob
2bd90 32 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 23 69  2);.}.#endif..#i
2bda0 66 64 65 66 20 4c 53 4d 5f 44 45 42 55 47 5f 45  fdef LSM_DEBUG_E
2bdb0 58 50 45 4e 53 49 56 45 0a 2f 2a 0a 2a 2a 20 54  XPENSIVE./*.** T
2bdc0 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
2bdd0 6f 6e 6c 79 20 69 6e 63 6c 75 64 65 64 20 69 6e  only included in
2bde0 20 74 68 65 20 62 75 69 6c 64 20 69 66 20 4c 53   the build if LS
2bdf0 4d 5f 44 45 42 55 47 5f 45 58 50 45 4e 53 49 56  M_DEBUG_EXPENSIV
2be00 45 20 69 73 20 0a 2a 2a 20 64 65 66 69 6e 65 64  E is .** defined
2be10 2e 20 49 74 73 20 6f 6e 6c 79 20 70 75 72 70 6f  . Its only purpo
2be20 73 65 20 69 73 20 74 6f 20 65 76 61 6c 75 61 74  se is to evaluat
2be30 65 20 76 61 72 69 6f 75 73 20 61 73 73 65 72 74  e various assert
2be40 28 29 20 73 74 61 74 65 6d 65 6e 74 73 20 74 6f  () statements to
2be50 20 0a 2a 2a 20 76 65 72 69 66 79 20 74 68 61 74   .** verify that
2be60 20 74 68 65 20 64 61 74 61 62 61 73 65 20 69 73   the database is
2be70 20 77 65 6c 6c 20 66 6f 72 6d 65 64 20 69 6e 20   well formed in 
2be80 63 65 72 74 61 69 6e 20 72 65 73 70 65 63 74 73  certain respects
2be90 2e 0a 2a 2a 0a 2a 2a 20 4d 6f 72 65 20 73 70 65  ..**.** More spe
2bea0 63 69 66 69 63 61 6c 6c 79 2c 20 69 74 20 63 68  cifically, it ch
2beb0 65 63 6b 73 20 74 68 61 74 20 74 68 65 20 61 72  ecks that the ar
2bec0 72 61 79 20 70 4f 6e 65 20 63 6f 6e 74 61 69 6e  ray pOne contain
2bed0 73 20 74 68 65 20 72 65 71 75 69 72 65 64 20 0a  s the required .
2bee0 2a 2a 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 70  ** pointers to p
2bef0 54 77 6f 2e 20 41 72 72 61 79 20 70 54 77 6f 20  Two. Array pTwo 
2bf00 6d 75 73 74 20 62 65 20 61 20 6d 61 69 6e 20 61  must be a main a
2bf10 72 72 61 79 2e 20 70 4f 6e 65 20 6d 61 79 20 62  rray. pOne may b
2bf20 65 20 65 69 74 68 65 72 20 61 20 0a 2a 2a 20 73  e either a .** s
2bf30 65 70 61 72 61 74 6f 72 73 20 61 72 72 61 79 20  eparators array 
2bf40 6f 72 20 61 6e 6f 74 68 65 72 20 6d 61 69 6e 20  or another main 
2bf50 61 72 72 61 79 2e 20 49 66 20 70 4f 6e 65 20 64  array. If pOne d
2bf60 6f 65 73 20 6e 6f 74 20 63 6f 6e 74 61 69 6e 20  oes not contain 
2bf70 74 68 65 20 0a 2a 2a 20 63 6f 72 72 65 63 74 20  the .** correct 
2bf80 73 65 74 20 6f 66 20 70 6f 69 6e 74 65 72 73 2c  set of pointers,
2bf90 20 61 6e 20 61 73 73 65 72 74 28 29 20 73 74 61   an assert() sta
2bfa0 74 65 6d 65 6e 74 20 66 61 69 6c 73 2e 0a 2a 2f  tement fails..*/
2bfb0 0a 73 74 61 74 69 63 20 69 6e 74 20 61 73 73 65  .static int asse
2bfc0 72 74 50 6f 69 6e 74 65 72 73 4f 6b 28 0a 20 20  rtPointersOk(.  
2bfd0 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20 20  lsm_db *pDb,    
2bfe0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2bff0 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64  /* Database hand
2c000 6c 65 20 2a 2f 0a 20 20 53 65 67 6d 65 6e 74 20  le */.  Segment 
2c010 2a 70 4f 6e 65 2c 20 20 20 20 20 20 20 20 20 20  *pOne,          
2c020 20 20 20 20 20 20 20 20 2f 2a 20 53 65 67 6d 65          /* Segme
2c030 6e 74 20 63 6f 6e 74 61 69 6e 69 6e 67 20 70 6f  nt containing po
2c040 69 6e 74 65 72 73 20 2a 2f 0a 20 20 53 65 67 6d  inters */.  Segm
2c050 65 6e 74 20 2a 70 54 77 6f 2c 20 20 20 20 20 20  ent *pTwo,      
2c060 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
2c070 65 67 6d 65 6e 74 20 63 6f 6e 74 61 69 6e 69 6e  egment containin
2c080 67 20 70 6f 69 6e 74 65 72 20 74 61 72 67 65 74  g pointer target
2c090 73 20 2a 2f 0a 20 20 69 6e 74 20 62 52 68 73 20  s */.  int bRhs 
2c0a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2c0b0 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
2c0c0 66 20 70 54 77 6f 20 6d 61 79 20 68 61 76 65 20  f pTwo may have 
2c0d0 62 65 65 6e 20 47 6f 62 62 6c 65 28 29 64 20 2a  been Gobble()d *
2c0e0 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  /.){.  int rc = 
2c0f0 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  LSM_OK;         
2c100 20 20 20 20 20 20 20 2f 2a 20 45 72 72 6f 72 20         /* Error 
2c110 63 6f 64 65 20 2a 2f 0a 20 20 53 65 67 6d 65 6e  code */.  Segmen
2c120 74 50 74 72 20 70 74 72 31 3b 20 20 20 20 20 20  tPtr ptr1;      
2c130 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65            /* Ite
2c140 72 61 74 65 73 20 74 68 72 6f 75 67 68 20 70 4f  rates through pO
2c150 6e 65 20 2a 2f 0a 20 20 53 65 67 6d 65 6e 74 50  ne */.  SegmentP
2c160 74 72 20 70 74 72 32 3b 20 20 20 20 20 20 20 20  tr ptr2;        
2c170 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61          /* Itera
2c180 74 65 73 20 74 68 72 6f 75 67 68 20 70 54 77 6f  tes through pTwo
2c190 20 2a 2f 0a 20 20 4c 73 6d 50 67 6e 6f 20 69 50   */.  LsmPgno iP
2c1a0 72 65 76 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  rev;..  assert( 
2c1b0 70 4f 6e 65 20 26 26 20 70 54 77 6f 20 29 3b 0a  pOne && pTwo );.
2c1c0 0a 20 20 6d 65 6d 73 65 74 28 26 70 74 72 31 2c  .  memset(&ptr1,
2c1d0 20 30 2c 20 73 69 7a 65 6f 66 28 70 74 72 31 29   0, sizeof(ptr1)
2c1e0 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 74 72  );.  memset(&ptr
2c1f0 32 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 74 72  2, 0, sizeof(ptr
2c200 31 29 29 3b 0a 20 20 70 74 72 31 2e 70 53 65 67  1));.  ptr1.pSeg
2c210 20 3d 20 70 4f 6e 65 3b 0a 20 20 70 74 72 32 2e   = pOne;.  ptr2.
2c220 70 53 65 67 20 3d 20 70 54 77 6f 3b 0a 20 20 73  pSeg = pTwo;.  s
2c230 65 67 6d 65 6e 74 50 74 72 45 6e 64 50 61 67 65  egmentPtrEndPage
2c240 28 70 44 62 2d 3e 70 46 53 2c 20 26 70 74 72 31  (pDb->pFS, &ptr1
2c250 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20 73 65 67  , 0, &rc);.  seg
2c260 6d 65 6e 74 50 74 72 45 6e 64 50 61 67 65 28 70  mentPtrEndPage(p
2c270 44 62 2d 3e 70 46 53 2c 20 26 70 74 72 32 2c 20  Db->pFS, &ptr2, 
2c280 30 2c 20 26 72 63 29 3b 0a 0a 20 20 2f 2a 20 43  0, &rc);..  /* C
2c290 68 65 63 6b 20 74 68 61 74 20 74 68 65 20 66 6f  heck that the fo
2c2a0 6f 74 65 72 20 70 6f 69 6e 74 65 72 20 6f 66 20  oter pointer of 
2c2b0 74 68 65 20 66 69 72 73 74 20 70 61 67 65 20 6f  the first page o
2c2c0 66 20 70 4f 6e 65 20 70 6f 69 6e 74 73 20 74 6f  f pOne points to
2c2d0 0a 20 20 2a 2a 20 74 68 65 20 66 69 72 73 74 20  .  ** the first 
2c2e0 70 61 67 65 20 6f 66 20 70 54 77 6f 2e 20 2a 2f  page of pTwo. */
2c2f0 0a 20 20 69 50 72 65 76 20 3d 20 70 54 77 6f 2d  .  iPrev = pTwo-
2c300 3e 69 46 69 72 73 74 3b 0a 20 20 69 66 28 20 70  >iFirst;.  if( p
2c310 74 72 31 2e 69 50 74 72 21 3d 69 50 72 65 76 20  tr1.iPtr!=iPrev 
2c320 26 26 20 21 62 52 68 73 20 29 7b 0a 20 20 20 20  && !bRhs ){.    
2c330 61 73 73 65 72 74 28 20 30 20 29 3b 0a 20 20 7d  assert( 0 );.  }
2c340 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f  ..  if( rc==LSM_
2c350 4f 4b 20 26 26 20 70 74 72 31 2e 6e 43 65 6c 6c  OK && ptr1.nCell
2c360 3e 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  >0 ){.    rc = s
2c370 65 67 6d 65 6e 74 50 74 72 4c 6f 61 64 43 65 6c  egmentPtrLoadCel
2c380 6c 28 26 70 74 72 31 2c 20 30 29 3b 0a 20 20 7d  l(&ptr1, 0);.  }
2c390 0a 20 20 20 20 20 20 0a 20 20 77 68 69 6c 65 28  .      .  while(
2c3a0 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70   rc==LSM_OK && p
2c3b0 74 72 32 2e 70 50 67 20 29 7b 0a 20 20 20 20 4c  tr2.pPg ){.    L
2c3c0 73 6d 50 67 6e 6f 20 69 54 68 69 73 3b 0a 0a 20  smPgno iThis;.. 
2c3d0 20 20 20 2f 2a 20 41 64 76 61 6e 63 65 20 74 6f     /* Advance to
2c3e0 20 74 68 65 20 6e 65 78 74 20 70 61 67 65 20 6f   the next page o
2c3f0 66 20 73 65 67 6d 65 6e 74 20 70 54 77 6f 20 74  f segment pTwo t
2c400 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 61 74 20  hat contains at 
2c410 6c 65 61 73 74 0a 20 20 20 20 2a 2a 20 6f 6e 65  least.    ** one
2c420 20 63 65 6c 6c 2e 20 42 72 65 61 6b 20 6f 75 74   cell. Break out
2c430 20 6f 66 20 74 68 65 20 6c 6f 6f 70 20 69 66 20   of the loop if 
2c440 74 68 65 20 69 74 65 72 61 74 6f 72 20 72 65 61  the iterator rea
2c450 63 68 65 73 20 45 4f 46 2e 20 20 2a 2f 0a 20 20  ches EOF.  */.  
2c460 20 20 64 6f 7b 0a 20 20 20 20 20 20 72 63 20 3d    do{.      rc =
2c470 20 73 65 67 6d 65 6e 74 50 74 72 4e 65 78 74 50   segmentPtrNextP
2c480 61 67 65 28 26 70 74 72 32 2c 20 31 29 3b 0a 20  age(&ptr2, 1);. 
2c490 20 20 20 20 20 61 73 73 65 72 74 28 20 72 63 3d       assert( rc=
2c4a0 3d 4c 53 4d 5f 4f 4b 20 29 3b 0a 20 20 20 20 7d  =LSM_OK );.    }
2c4b0 77 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f 4f  while( rc==LSM_O
2c4c0 4b 20 26 26 20 70 74 72 32 2e 70 50 67 20 26 26  K && ptr2.pPg &&
2c4d0 20 70 74 72 32 2e 6e 43 65 6c 6c 3d 3d 30 20 29   ptr2.nCell==0 )
2c4e0 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 4c 53  ;.    if( rc!=LS
2c4f0 4d 5f 4f 4b 20 7c 7c 20 70 74 72 32 2e 70 50 67  M_OK || ptr2.pPg
2c500 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  ==0 ) break;.   
2c510 20 69 54 68 69 73 20 3d 20 6c 73 6d 46 73 50 61   iThis = lsmFsPa
2c520 67 65 4e 75 6d 62 65 72 28 70 74 72 32 2e 70 50  geNumber(ptr2.pP
2c530 67 29 3b 0a 0a 20 20 20 20 69 66 28 20 28 70 74  g);..    if( (pt
2c540 72 32 2e 66 6c 61 67 73 20 26 20 28 50 47 46 54  r2.flags & (PGFT
2c550 52 5f 53 4b 49 50 5f 54 48 49 53 5f 46 4c 41 47  R_SKIP_THIS_FLAG
2c560 7c 53 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46  |SEGMENT_BTREE_F
2c570 4c 41 47 29 29 3d 3d 30 20 29 7b 0a 0a 20 20 20  LAG))==0 ){..   
2c580 20 20 20 2f 2a 20 4c 6f 61 64 20 74 68 65 20 66     /* Load the f
2c590 69 72 73 74 20 63 65 6c 6c 20 69 6e 20 74 68 65  irst cell in the
2c5a0 20 61 72 72 61 79 20 70 54 77 6f 20 70 61 67 65   array pTwo page
2c5b0 2e 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20  . */.      rc = 
2c5c0 73 65 67 6d 65 6e 74 50 74 72 4c 6f 61 64 43 65  segmentPtrLoadCe
2c5d0 6c 6c 28 26 70 74 72 32 2c 20 30 29 3b 0a 0a 20  ll(&ptr2, 0);.. 
2c5e0 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74 65 20       /* Iterate 
2c5f0 66 6f 72 77 61 72 64 73 20 74 68 72 6f 75 67 68  forwards through
2c600 20 70 4f 6e 65 2c 20 73 65 61 72 63 68 69 6e 67   pOne, searching
2c610 20 66 6f 72 20 61 20 6b 65 79 20 74 68 61 74 20   for a key that 
2c620 6d 61 74 63 68 65 73 20 74 68 65 0a 20 20 20 20  matches the.    
2c630 20 20 2a 2a 20 6b 65 79 20 70 74 72 32 2e 70 4b    ** key ptr2.pK
2c640 65 79 2f 6e 4b 65 79 2e 20 54 68 69 73 20 6b 65  ey/nKey. This ke
2c650 79 20 73 68 6f 75 6c 64 20 68 61 76 65 20 61 20  y should have a 
2c660 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 70  pointer to the p
2c670 61 67 65 20 74 68 61 74 0a 20 20 20 20 20 20 2a  age that.      *
2c680 2a 20 70 74 72 32 20 63 75 72 72 65 6e 74 6c 79  * ptr2 currently
2c690 20 70 6f 69 6e 74 73 20 74 6f 2e 20 2a 2f 0a 20   points to. */. 
2c6a0 20 20 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d       while( rc==
2c6b0 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  LSM_OK ){.      
2c6c0 20 20 69 6e 74 20 72 65 73 20 3d 20 72 74 54 6f    int res = rtTo
2c6d0 70 69 63 28 70 74 72 31 2e 65 54 79 70 65 29 20  pic(ptr1.eType) 
2c6e0 2d 20 72 74 54 6f 70 69 63 28 70 74 72 32 2e 65  - rtTopic(ptr2.e
2c6f0 54 79 70 65 29 3b 0a 20 20 20 20 20 20 20 20 69  Type);.        i
2c700 66 28 20 72 65 73 3d 3d 30 20 29 7b 0a 20 20 20  f( res==0 ){.   
2c710 20 20 20 20 20 20 20 72 65 73 20 3d 20 70 44 62         res = pDb
2c720 2d 3e 78 43 6d 70 28 70 74 72 31 2e 70 4b 65 79  ->xCmp(ptr1.pKey
2c730 2c 20 70 74 72 31 2e 6e 4b 65 79 2c 20 70 74 72  , ptr1.nKey, ptr
2c740 32 2e 70 4b 65 79 2c 20 70 74 72 32 2e 6e 4b 65  2.pKey, ptr2.nKe
2c750 79 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20  y);.        }.. 
2c760 20 20 20 20 20 20 20 69 66 28 20 72 65 73 3c 30         if( res<0
2c770 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 61 73   ){.          as
2c780 73 65 72 74 28 20 62 52 68 73 20 7c 7c 20 70 74  sert( bRhs || pt
2c790 72 31 2e 69 50 74 72 2b 70 74 72 31 2e 69 50 67  r1.iPtr+ptr1.iPg
2c7a0 50 74 72 3d 3d 69 50 72 65 76 20 29 3b 0a 20 20  Ptr==iPrev );.  
2c7b0 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
2c7c0 72 65 73 3e 30 20 29 7b 0a 20 20 20 20 20 20 20  res>0 ){.       
2c7d0 20 20 20 61 73 73 65 72 74 28 20 30 20 29 3b 0a     assert( 0 );.
2c7e0 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
2c7f0 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
2c800 20 70 74 72 31 2e 69 50 74 72 2b 70 74 72 31 2e   ptr1.iPtr+ptr1.
2c810 69 50 67 50 74 72 3d 3d 69 54 68 69 73 20 29 3b  iPgPtr==iThis );
2c820 0a 20 20 20 20 20 20 20 20 20 20 69 50 72 65 76  .          iPrev
2c830 20 3d 20 69 54 68 69 73 3b 0a 20 20 20 20 20 20   = iThis;.      
2c840 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
2c850 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 72 63     }..        rc
2c860 20 3d 20 73 65 67 6d 65 6e 74 50 74 72 41 64 76   = segmentPtrAdv
2c870 61 6e 63 65 28 30 2c 20 26 70 74 72 31 2c 20 30  ance(0, &ptr1, 0
2c880 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  );.        if( p
2c890 74 72 31 2e 70 50 67 3d 3d 30 20 29 7b 0a 20 20  tr1.pPg==0 ){.  
2c8a0 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
2c8b0 30 20 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  0 );.        }. 
2c8c0 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
2c8d0 0a 0a 20 20 73 65 67 6d 65 6e 74 50 74 72 52 65  ..  segmentPtrRe
2c8e0 73 65 74 28 26 70 74 72 31 2c 20 30 29 3b 0a 20  set(&ptr1, 0);. 
2c8f0 20 73 65 67 6d 65 6e 74 50 74 72 52 65 73 65 74   segmentPtrReset
2c900 28 26 70 74 72 32 2c 20 30 29 3b 0a 20 20 72 65  (&ptr2, 0);.  re
2c910 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 7d 0a 0a  turn LSM_OK;.}..
2c920 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
2c930 69 6f 6e 20 69 73 20 6f 6e 6c 79 20 69 6e 63 6c  ion is only incl
2c940 75 64 65 64 20 69 6e 20 74 68 65 20 62 75 69 6c  uded in the buil
2c950 64 20 69 66 20 4c 53 4d 5f 44 45 42 55 47 5f 45  d if LSM_DEBUG_E
2c960 58 50 45 4e 53 49 56 45 20 69 73 20 0a 2a 2a 20  XPENSIVE is .** 
2c970 64 65 66 69 6e 65 64 2e 20 49 74 73 20 6f 6e 6c  defined. Its onl
2c980 79 20 70 75 72 70 6f 73 65 20 69 73 20 74 6f 20  y purpose is to 
2c990 65 76 61 6c 75 61 74 65 20 76 61 72 69 6f 75 73  evaluate various
2c9a0 20 61 73 73 65 72 74 28 29 20 73 74 61 74 65 6d   assert() statem
2c9b0 65 6e 74 73 20 74 6f 20 0a 2a 2a 20 76 65 72 69  ents to .** veri
2c9c0 66 79 20 74 68 61 74 20 74 68 65 20 64 61 74 61  fy that the data
2c9d0 62 61 73 65 20 69 73 20 77 65 6c 6c 20 66 6f 72  base is well for
2c9e0 6d 65 64 20 69 6e 20 63 65 72 74 61 69 6e 20 72  med in certain r
2c9f0 65 73 70 65 63 74 73 2e 0a 2a 2a 0a 2a 2a 20 4d  espects..**.** M
2ca00 6f 72 65 20 73 70 65 63 69 66 69 63 61 6c 6c 79  ore specifically
2ca10 2c 20 69 74 20 63 68 65 63 6b 73 20 74 68 61 74  , it checks that
2ca20 20 74 68 65 20 62 2d 74 72 65 65 20 65 6d 62 65   the b-tree embe
2ca30 64 64 65 64 20 69 6e 20 61 72 72 61 79 20 70 52  dded in array pR
2ca40 75 6e 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 74  un.** contains t
2ca50 68 65 20 63 6f 72 72 65 63 74 20 6b 65 79 73 2e  he correct keys.
2ca60 20 49 66 20 6e 6f 74 2c 20 61 6e 20 61 73 73 65   If not, an asse
2ca70 72 74 28 29 20 66 61 69 6c 73 2e 0a 2a 2f 0a 73  rt() fails..*/.s
2ca80 74 61 74 69 63 20 69 6e 74 20 61 73 73 65 72 74  tatic int assert
2ca90 42 74 72 65 65 4f 6b 28 0a 20 20 6c 73 6d 5f 64  BtreeOk(.  lsm_d
2caa0 62 20 2a 70 44 62 2c 0a 20 20 53 65 67 6d 65 6e  b *pDb,.  Segmen
2cab0 74 20 2a 70 53 65 67 0a 29 7b 0a 20 20 69 6e 74  t *pSeg.){.  int
2cac0 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20   rc = LSM_OK;   
2cad0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2cae0 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
2caf0 20 69 66 28 20 70 53 65 67 2d 3e 69 52 6f 6f 74   if( pSeg->iRoot
2cb00 20 29 7b 0a 20 20 20 20 4c 73 6d 42 6c 6f 62 20   ){.    LsmBlob 
2cb10 62 6c 6f 62 20 3d 20 7b 30 2c 20 30 2c 20 30 7d  blob = {0, 0, 0}
2cb20 3b 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20  ;     /* Buffer 
2cb30 75 73 65 64 20 74 6f 20 63 61 63 68 65 20 6f 76  used to cache ov
2cb40 65 72 66 6c 6f 77 20 6b 65 79 73 20 2a 2f 0a 20  erflow keys */. 
2cb50 20 20 20 46 69 6c 65 53 79 73 74 65 6d 20 2a 70     FileSystem *p
2cb60 46 53 20 3d 20 70 44 62 2d 3e 70 46 53 3b 20 20  FS = pDb->pFS;  
2cb70 20 2f 2a 20 46 69 6c 65 20 73 79 73 74 65 6d 20   /* File system 
2cb80 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a  to read from */.
2cb90 20 20 20 20 50 61 67 65 20 2a 70 50 67 20 3d 20      Page *pPg = 
2cba0 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
2cbb0 20 20 2f 2a 20 4d 61 69 6e 20 72 75 6e 20 70 61    /* Main run pa
2cbc0 67 65 20 2a 2f 0a 20 20 20 20 42 74 72 65 65 43  ge */.    BtreeC
2cbd0 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 30 3b  ursor *pCsr = 0;
2cbe0 20 20 20 20 20 20 20 20 2f 2a 20 42 74 72 65 65          /* Btree
2cbf0 20 63 75 72 73 6f 72 20 2a 2f 0a 0a 20 20 20 20   cursor */..    
2cc00 72 63 20 3d 20 62 74 72 65 65 43 75 72 73 6f 72  rc = btreeCursor
2cc10 4e 65 77 28 70 44 62 2c 20 70 53 65 67 2c 20 26  New(pDb, pSeg, &
2cc20 70 43 73 72 29 3b 0a 20 20 20 20 69 66 28 20 72  pCsr);.    if( r
2cc30 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
2cc40 20 20 20 72 63 20 3d 20 62 74 72 65 65 43 75 72     rc = btreeCur
2cc50 73 6f 72 46 69 72 73 74 28 70 43 73 72 29 3b 0a  sorFirst(pCsr);.
2cc60 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63      }.    if( rc
2cc70 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20  ==LSM_OK ){.    
2cc80 20 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50 61    rc = lsmFsDbPa
2cc90 67 65 47 65 74 28 70 46 53 2c 20 70 53 65 67 2c  geGet(pFS, pSeg,
2cca0 20 70 53 65 67 2d 3e 69 46 69 72 73 74 2c 20 26   pSeg->iFirst, &
2ccb0 70 50 67 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  pPg);.    }..   
2ccc0 20 77 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d 5f   while( rc==LSM_
2ccd0 4f 4b 20 29 7b 0a 20 20 20 20 20 20 50 61 67 65  OK ){.      Page
2cce0 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 75   *pNext;.      u
2ccf0 38 20 2a 61 44 61 74 61 3b 0a 20 20 20 20 20 20  8 *aData;.      
2cd00 69 6e 74 20 6e 44 61 74 61 3b 0a 20 20 20 20 20  int nData;.     
2cd10 20 69 6e 74 20 66 6c 61 67 73 3b 0a 0a 20 20 20   int flags;..   
2cd20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 44 62 50     rc = lsmFsDbP
2cd30 61 67 65 4e 65 78 74 28 70 53 65 67 2c 20 70 50  ageNext(pSeg, pP
2cd40 67 2c 20 31 2c 20 26 70 4e 65 78 74 29 3b 0a 20  g, 1, &pNext);. 
2cd50 20 20 20 20 20 6c 73 6d 46 73 50 61 67 65 52 65       lsmFsPageRe
2cd60 6c 65 61 73 65 28 70 50 67 29 3b 0a 20 20 20 20  lease(pPg);.    
2cd70 20 20 70 50 67 20 3d 20 70 4e 65 78 74 3b 0a 20    pPg = pNext;. 
2cd80 20 20 20 20 20 69 66 28 20 70 50 67 3d 3d 30 20       if( pPg==0 
2cd90 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 61  ) break;.      a
2cda0 44 61 74 61 20 3d 20 66 73 50 61 67 65 44 61 74  Data = fsPageDat
2cdb0 61 28 70 50 67 2c 20 26 6e 44 61 74 61 29 3b 0a  a(pPg, &nData);.
2cdc0 20 20 20 20 20 20 66 6c 61 67 73 20 3d 20 70 61        flags = pa
2cdd0 67 65 47 65 74 46 6c 61 67 73 28 61 44 61 74 61  geGetFlags(aData
2cde0 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20  , nData);.      
2cdf0 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 0a  if( rc==LSM_OK .
2ce00 20 20 20 20 20 20 20 26 26 20 30 3d 3d 28 28 53         && 0==((S
2ce10 45 47 4d 45 4e 54 5f 42 54 52 45 45 5f 46 4c 41  EGMENT_BTREE_FLA
2ce20 47 7c 50 47 46 54 52 5f 53 4b 49 50 5f 54 48 49  G|PGFTR_SKIP_THI
2ce30 53 5f 46 4c 41 47 29 20 26 20 66 6c 61 67 73 29  S_FLAG) & flags)
2ce40 0a 20 20 20 20 20 20 20 26 26 20 30 21 3d 70 61  .       && 0!=pa
2ce50 67 65 47 65 74 4e 52 65 63 28 61 44 61 74 61 2c  geGetNRec(aData,
2ce60 20 6e 44 61 74 61 29 0a 20 20 20 20 20 20 29 7b   nData).      ){
2ce70 0a 20 20 20 20 20 20 20 20 75 38 20 2a 70 4b 65  .        u8 *pKe
2ce80 79 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e  y;.        int n
2ce90 4b 65 79 3b 0a 20 20 20 20 20 20 20 20 69 6e 74  Key;.        int
2cea0 20 69 54 6f 70 69 63 3b 0a 20 20 20 20 20 20 20   iTopic;.       
2ceb0 20 70 4b 65 79 20 3d 20 70 61 67 65 47 65 74 4b   pKey = pageGetK
2cec0 65 79 28 70 53 65 67 2c 20 70 50 67 2c 20 30 2c  ey(pSeg, pPg, 0,
2ced0 20 26 69 54 6f 70 69 63 2c 20 26 6e 4b 65 79 2c   &iTopic, &nKey,
2cee0 20 26 62 6c 6f 62 29 3b 0a 20 20 20 20 20 20 20   &blob);.       
2cef0 20 61 73 73 65 72 74 28 20 6e 4b 65 79 3d 3d 70   assert( nKey==p
2cf00 43 73 72 2d 3e 6e 4b 65 79 20 26 26 20 30 3d 3d  Csr->nKey && 0==
2cf10 6d 65 6d 63 6d 70 28 70 4b 65 79 2c 20 70 43 73  memcmp(pKey, pCs
2cf20 72 2d 3e 70 4b 65 79 2c 20 6e 4b 65 79 29 20 29  r->pKey, nKey) )
2cf30 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  ;.        assert
2cf40 28 20 6c 73 6d 46 73 50 61 67 65 4e 75 6d 62 65  ( lsmFsPageNumbe
2cf50 72 28 70 50 67 29 3d 3d 70 43 73 72 2d 3e 69 50  r(pPg)==pCsr->iP
2cf60 74 72 20 29 3b 0a 20 20 20 20 20 20 20 20 72 63  tr );.        rc
2cf70 20 3d 20 62 74 72 65 65 43 75 72 73 6f 72 4e 65   = btreeCursorNe
2cf80 78 74 28 70 43 73 72 29 3b 0a 20 20 20 20 20 20  xt(pCsr);.      
2cf90 7d 0a 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65  }.    }.    asse
2cfa0 72 74 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 7c  rt( rc!=LSM_OK |
2cfb0 7c 20 70 43 73 72 2d 3e 70 4b 65 79 3d 3d 30 20  | pCsr->pKey==0 
2cfc0 29 3b 0a 0a 20 20 20 20 69 66 28 20 70 50 67 20  );..    if( pPg 
2cfd0 29 20 6c 73 6d 46 73 50 61 67 65 52 65 6c 65 61  ) lsmFsPageRelea
2cfe0 73 65 28 70 50 67 29 3b 0a 0a 20 20 20 20 62 74  se(pPg);..    bt
2cff0 72 65 65 43 75 72 73 6f 72 46 72 65 65 28 70 43  reeCursorFree(pC
2d000 73 72 29 3b 0a 20 20 20 20 73 6f 72 74 65 64 42  sr);.    sortedB
2d010 6c 6f 62 46 72 65 65 28 26 62 6c 6f 62 29 3b 0a  lobFree(&blob);.
2d020 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
2d030 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 69 66  ;.}.#endif /* if
2d040 64 65 66 20 4c 53 4d 5f 44 45 42 55 47 5f 45 58  def LSM_DEBUG_EX
2d050 50 45 4e 53 49 56 45 20 2a 2f 0a                 PENSIVE */.