/ Hex Artifact Content
Login

Artifact b5703f8042e71d3a2d65e671f6832e077e79e89e9975818f67f969922618db63:


0000: 2f 2a 0a 2a 2a 20 32 30 31 31 2d 30 38 2d 31 38  /*.** 2011-08-18
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a  ***************.
0170: 2a 2a 0a 2a 2a 20 54 68 65 20 6d 61 69 6e 20 69  **.** The main i
0180: 6e 74 65 72 66 61 63 65 20 74 6f 20 74 68 65 20  nterface to the 
0190: 4c 53 4d 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 23  LSM module..*/.#
01a0: 69 6e 63 6c 75 64 65 20 22 6c 73 6d 49 6e 74 2e  include "lsmInt.
01b0: 68 22 0a 0a 0a 23 69 66 64 65 66 20 4c 53 4d 5f  h"...#ifdef LSM_
01c0: 44 45 42 55 47 0a 2f 2a 0a 2a 2a 20 54 68 69 73  DEBUG./*.** This
01d0: 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e   function return
01e0: 73 20 61 20 63 6f 70 79 20 6f 66 20 69 74 73 20  s a copy of its 
01f0: 6f 6e 6c 79 20 61 72 67 75 6d 65 6e 74 2e 0a 2a  only argument..*
0200: 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 6c 69  *.** When the li
0210: 62 72 61 72 79 20 69 73 20 62 75 69 6c 74 20 77  brary is built w
0220: 69 74 68 20 4c 53 4d 5f 44 45 42 55 47 20 64 65  ith LSM_DEBUG de
0230: 66 69 6e 65 64 2c 20 74 68 69 73 20 66 75 6e 63  fined, this func
0240: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 0a 2a  tion is called.*
0250: 2a 20 77 68 65 6e 65 76 65 72 20 61 6e 20 65 72  * whenever an er
0260: 72 6f 72 20 63 6f 64 65 20 69 73 20 67 65 6e 65  ror code is gene
0270: 72 61 74 65 64 20 28 6e 6f 74 20 70 72 6f 70 61  rated (not propa
0280: 67 61 74 65 64 20 2d 20 67 65 6e 65 72 61 74 65  gated - generate
0290: 64 29 2e 20 53 6f 0a 2a 2a 20 69 66 20 74 68 65  d). So.** if the
02a0: 20 6c 69 62 72 61 72 79 20 69 73 20 6d 79 73 74   library is myst
02b0: 65 72 69 6f 75 73 6c 79 20 72 65 74 75 72 6e 69  eriously returni
02c0: 6e 67 20 28 73 61 79 29 20 4c 53 4d 5f 49 4f 45  ng (say) LSM_IOE
02d0: 52 52 2c 20 61 20 62 72 65 61 6b 70 6f 69 6e 74  RR, a breakpoint
02e0: 0a 2a 2a 20 6d 61 79 20 62 65 20 73 65 74 20 69  .** may be set i
02f0: 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
0300: 74 6f 20 64 65 74 65 72 6d 69 6e 65 20 77 68 79  to determine why
0310: 2e 0a 2a 2f 0a 69 6e 74 20 6c 73 6d 45 72 72 6f  ..*/.int lsmErro
0320: 72 42 6b 70 74 28 69 6e 74 20 72 63 29 7b 0a 20  rBkpt(int rc){. 
0330: 20 2f 2a 20 53 65 74 20 62 72 65 61 6b 70 6f 69   /* Set breakpoi
0340: 6e 74 20 68 65 72 65 21 20 2a 2f 0a 20 20 72 65  nt here! */.  re
0350: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
0360: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
0370: 63 6f 6e 74 61 69 6e 73 20 76 61 72 69 6f 75 73  contains various
0380: 20 61 73 73 65 72 74 28 29 20 73 74 61 74 65 6d   assert() statem
0390: 65 6e 74 73 20 74 68 61 74 20 74 65 73 74 20 74  ents that test t
03a0: 68 61 74 20 74 68 65 0a 2a 2a 20 6c 73 6d 5f 64  hat the.** lsm_d
03b0: 62 20 73 74 72 75 63 74 75 72 65 20 70 61 73 73  b structure pass
03c0: 65 64 20 61 73 20 61 6e 20 61 72 67 75 6d 65 6e  ed as an argumen
03d0: 74 20 69 73 20 69 6e 74 65 72 6e 61 6c 6c 79 20  t is internally 
03e0: 63 6f 6e 73 69 73 74 65 6e 74 2e 0a 2a 2f 0a 73  consistent..*/.s
03f0: 74 61 74 69 63 20 76 6f 69 64 20 61 73 73 65 72  tatic void asser
0400: 74 5f 64 62 5f 73 74 61 74 65 28 6c 73 6d 5f 64  t_db_state(lsm_d
0410: 62 20 2a 70 44 62 29 7b 0a 0a 20 20 2f 2a 20 49  b *pDb){..  /* I
0420: 66 20 74 68 65 72 65 20 69 73 20 61 74 20 6c 65  f there is at le
0430: 61 73 74 20 6f 6e 65 20 63 75 72 73 6f 72 20 6f  ast one cursor o
0440: 72 20 61 20 77 72 69 74 65 20 74 72 61 6e 73 61  r a write transa
0450: 63 74 69 6f 6e 20 6f 70 65 6e 2c 20 74 68 65 20  ction open, the 
0460: 64 61 74 61 62 61 73 65 0a 20 20 2a 2a 20 68 61  database.  ** ha
0470: 6e 64 6c 65 20 6d 75 73 74 20 62 65 20 68 6f 6c  ndle must be hol
0480: 64 69 6e 67 20 61 20 70 6f 69 6e 74 65 72 20 74  ding a pointer t
0490: 6f 20 61 20 63 6c 69 65 6e 74 20 73 6e 61 70 73  o a client snaps
04a0: 68 6f 74 2e 20 41 6e 64 20 74 68 65 20 72 65 76  hot. And the rev
04b0: 65 72 73 65 20 0a 20 20 2a 2a 20 2d 20 69 66 20  erse .  ** - if 
04c0: 74 68 65 72 65 20 61 72 65 20 6e 6f 20 6f 70 65  there are no ope
04d0: 6e 20 63 75 72 73 6f 72 73 20 61 6e 64 20 6e 6f  n cursors and no
04e0: 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69   write transacti
04f0: 6f 6e 73 20 74 68 65 6e 20 74 68 65 72 65 20 6d  ons then there m
0500: 75 73 74 20 0a 20 20 2a 2a 20 6e 6f 74 20 62 65  ust .  ** not be
0510: 20 61 20 63 6c 69 65 6e 74 20 73 6e 61 70 73 68   a client snapsh
0520: 6f 74 2e 20 20 2a 2f 0a 20 20 0a 20 20 61 73 73  ot.  */.  .  ass
0530: 65 72 74 28 20 28 70 44 62 2d 3e 70 43 73 72 21  ert( (pDb->pCsr!
0540: 3d 30 7c 7c 70 44 62 2d 3e 6e 54 72 61 6e 73 4f  =0||pDb->nTransO
0550: 70 65 6e 3e 30 29 3d 3d 28 70 44 62 2d 3e 69 52  pen>0)==(pDb->iR
0560: 65 61 64 65 72 3e 3d 30 7c 7c 70 44 62 2d 3e 62  eader>=0||pDb->b
0570: 52 6f 54 72 61 6e 73 29 20 29 3b 0a 0a 20 20 61  RoTrans) );..  a
0580: 73 73 65 72 74 28 20 28 70 44 62 2d 3e 69 52 65  ssert( (pDb->iRe
0590: 61 64 65 72 3c 30 20 26 26 20 70 44 62 2d 3e 62  ader<0 && pDb->b
05a0: 52 6f 54 72 61 6e 73 3d 3d 30 29 20 7c 7c 20 70  RoTrans==0) || p
05b0: 44 62 2d 3e 70 43 6c 69 65 6e 74 21 3d 30 20 29  Db->pClient!=0 )
05c0: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 44 62  ;..  assert( pDb
05d0: 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 3e 3d 30 20  ->nTransOpen>=0 
05e0: 29 3b 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65 66  );.}.#else.# def
05f0: 69 6e 65 20 61 73 73 65 72 74 5f 64 62 5f 73 74  ine assert_db_st
0600: 61 74 65 28 78 29 20 0a 23 65 6e 64 69 66 0a 0a  ate(x) .#endif..
0610: 2f 2a 0a 2a 2a 20 54 68 65 20 64 65 66 61 75 6c  /*.** The defaul
0620: 74 20 6b 65 79 2d 63 6f 6d 70 61 72 65 20 66 75  t key-compare fu
0630: 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69  nction..*/.stati
0640: 63 20 69 6e 74 20 78 43 6d 70 28 76 6f 69 64 20  c int xCmp(void 
0650: 2a 70 31 2c 20 69 6e 74 20 6e 31 2c 20 76 6f 69  *p1, int n1, voi
0660: 64 20 2a 70 32 2c 20 69 6e 74 20 6e 32 29 7b 0a  d *p2, int n2){.
0670: 20 20 69 6e 74 20 72 65 73 3b 0a 20 20 72 65 73    int res;.  res
0680: 20 3d 20 6d 65 6d 63 6d 70 28 70 31 2c 20 70 32   = memcmp(p1, p2
0690: 2c 20 4c 53 4d 5f 4d 49 4e 28 6e 31 2c 20 6e 32  , LSM_MIN(n1, n2
06a0: 29 29 3b 0a 20 20 69 66 28 20 72 65 73 3d 3d 30  ));.  if( res==0
06b0: 20 29 20 72 65 73 20 3d 20 28 6e 31 2d 6e 32 29   ) res = (n1-n2)
06c0: 3b 0a 20 20 72 65 74 75 72 6e 20 72 65 73 3b 0a  ;.  return res;.
06d0: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 78  }..static void x
06e0: 4c 6f 67 28 76 6f 69 64 20 2a 70 43 74 78 2c 20  Log(void *pCtx, 
06f0: 69 6e 74 20 72 63 2c 20 63 6f 6e 73 74 20 63 68  int rc, const ch
0700: 61 72 20 2a 7a 29 7b 0a 20 20 28 76 6f 69 64 29  ar *z){.  (void)
0710: 28 72 63 29 3b 0a 20 20 28 76 6f 69 64 29 28 70  (rc);.  (void)(p
0720: 43 74 78 29 3b 0a 20 20 66 70 72 69 6e 74 66 28  Ctx);.  fprintf(
0730: 73 74 64 65 72 72 2c 20 22 25 73 5c 6e 22 2c 20  stderr, "%s\n", 
0740: 7a 29 3b 0a 20 20 66 66 6c 75 73 68 28 73 74 64  z);.  fflush(std
0750: 65 72 72 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  err);.}../*.** A
0760: 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 64 62  llocate a new db
0770: 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a 69 6e 74 20   handle..*/.int 
0780: 6c 73 6d 5f 6e 65 77 28 6c 73 6d 5f 65 6e 76 20  lsm_new(lsm_env 
0790: 2a 70 45 6e 76 2c 20 6c 73 6d 5f 64 62 20 2a 2a  *pEnv, lsm_db **
07a0: 70 70 44 62 29 7b 0a 20 20 6c 73 6d 5f 64 62 20  ppDb){.  lsm_db 
07b0: 2a 70 44 62 3b 0a 0a 20 20 2f 2a 20 49 66 20 74  *pDb;..  /* If t
07c0: 68 65 20 75 73 65 72 20 64 69 64 20 6e 6f 74 20  he user did not 
07d0: 70 72 6f 76 69 64 65 20 61 6e 20 65 6e 76 69 72  provide an envir
07e0: 6f 6e 6d 65 6e 74 2c 20 75 73 65 20 74 68 65 20  onment, use the 
07f0: 64 65 66 61 75 6c 74 2e 20 2a 2f 0a 20 20 69 66  default. */.  if
0800: 28 20 70 45 6e 76 3d 3d 30 20 29 20 70 45 6e 76  ( pEnv==0 ) pEnv
0810: 20 3d 20 6c 73 6d 5f 64 65 66 61 75 6c 74 5f 65   = lsm_default_e
0820: 6e 76 28 29 3b 0a 20 20 61 73 73 65 72 74 28 20  nv();.  assert( 
0830: 70 45 6e 76 20 29 3b 0a 0a 20 20 2f 2a 20 41 6c  pEnv );..  /* Al
0840: 6c 6f 63 61 74 65 20 74 68 65 20 6e 65 77 20 64  locate the new d
0850: 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a  atabase handle *
0860: 2f 0a 20 20 2a 70 70 44 62 20 3d 20 70 44 62 20  /.  *ppDb = pDb 
0870: 3d 20 28 6c 73 6d 5f 64 62 20 2a 29 6c 73 6d 4d  = (lsm_db *)lsmM
0880: 61 6c 6c 6f 63 5a 65 72 6f 28 70 45 6e 76 2c 20  allocZero(pEnv, 
0890: 73 69 7a 65 6f 66 28 6c 73 6d 5f 64 62 29 29 3b  sizeof(lsm_db));
08a0: 0a 20 20 69 66 28 20 70 44 62 3d 3d 30 20 29 20  .  if( pDb==0 ) 
08b0: 72 65 74 75 72 6e 20 4c 53 4d 5f 4e 4f 4d 45 4d  return LSM_NOMEM
08c0: 5f 42 4b 50 54 3b 0a 0a 20 20 2f 2a 20 49 6e 69  _BKPT;..  /* Ini
08d0: 74 69 61 6c 69 7a 65 20 74 68 65 20 6e 65 77 20  tialize the new 
08e0: 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 70 44 62 2d  object */.  pDb-
08f0: 3e 70 45 6e 76 20 3d 20 70 45 6e 76 3b 0a 20 20  >pEnv = pEnv;.  
0900: 70 44 62 2d 3e 6e 54 72 65 65 4c 69 6d 69 74 20  pDb->nTreeLimit 
0910: 3d 20 4c 53 4d 5f 44 46 4c 54 5f 41 55 54 4f 46  = LSM_DFLT_AUTOF
0920: 4c 55 53 48 3b 0a 20 20 70 44 62 2d 3e 6e 41 75  LUSH;.  pDb->nAu
0930: 74 6f 63 6b 70 74 20 3d 20 4c 53 4d 5f 44 46 4c  tockpt = LSM_DFL
0940: 54 5f 41 55 54 4f 43 48 45 43 4b 50 4f 49 4e 54  T_AUTOCHECKPOINT
0950: 3b 0a 20 20 70 44 62 2d 3e 62 41 75 74 6f 77 6f  ;.  pDb->bAutowo
0960: 72 6b 20 3d 20 4c 53 4d 5f 44 46 4c 54 5f 41 55  rk = LSM_DFLT_AU
0970: 54 4f 57 4f 52 4b 3b 0a 20 20 70 44 62 2d 3e 65  TOWORK;.  pDb->e
0980: 53 61 66 65 74 79 20 3d 20 4c 53 4d 5f 44 46 4c  Safety = LSM_DFL
0990: 54 5f 53 41 46 45 54 59 3b 0a 20 20 70 44 62 2d  T_SAFETY;.  pDb-
09a0: 3e 78 43 6d 70 20 3d 20 78 43 6d 70 3b 0a 20 20  >xCmp = xCmp;.  
09b0: 70 44 62 2d 3e 6e 44 66 6c 74 50 67 73 7a 20 3d  pDb->nDfltPgsz =
09c0: 20 4c 53 4d 5f 44 46 4c 54 5f 50 41 47 45 5f 53   LSM_DFLT_PAGE_S
09d0: 49 5a 45 3b 0a 20 20 70 44 62 2d 3e 6e 44 66 6c  IZE;.  pDb->nDfl
09e0: 74 42 6c 6b 73 7a 20 3d 20 4c 53 4d 5f 44 46 4c  tBlksz = LSM_DFL
09f0: 54 5f 42 4c 4f 43 4b 5f 53 49 5a 45 3b 0a 20 20  T_BLOCK_SIZE;.  
0a00: 70 44 62 2d 3e 6e 4d 65 72 67 65 20 3d 20 4c 53  pDb->nMerge = LS
0a10: 4d 5f 44 46 4c 54 5f 41 55 54 4f 4d 45 52 47 45  M_DFLT_AUTOMERGE
0a20: 3b 0a 20 20 70 44 62 2d 3e 6e 4d 61 78 46 72 65  ;.  pDb->nMaxFre
0a30: 65 6c 69 73 74 20 3d 20 4c 53 4d 5f 4d 41 58 5f  elist = LSM_MAX_
0a40: 46 52 45 45 4c 49 53 54 5f 45 4e 54 52 49 45 53  FREELIST_ENTRIES
0a50: 3b 0a 20 20 70 44 62 2d 3e 62 55 73 65 4c 6f 67  ;.  pDb->bUseLog
0a60: 20 3d 20 4c 53 4d 5f 44 46 4c 54 5f 55 53 45 5f   = LSM_DFLT_USE_
0a70: 4c 4f 47 3b 0a 20 20 70 44 62 2d 3e 69 52 65 61  LOG;.  pDb->iRea
0a80: 64 65 72 20 3d 20 2d 31 3b 0a 20 20 70 44 62 2d  der = -1;.  pDb-
0a90: 3e 69 52 77 63 6c 69 65 6e 74 20 3d 20 2d 31 3b  >iRwclient = -1;
0aa0: 0a 20 20 70 44 62 2d 3e 62 4d 75 6c 74 69 50 72  .  pDb->bMultiPr
0ab0: 6f 63 20 3d 20 4c 53 4d 5f 44 46 4c 54 5f 4d 55  oc = LSM_DFLT_MU
0ac0: 4c 54 49 50 4c 45 5f 50 52 4f 43 45 53 53 45 53  LTIPLE_PROCESSES
0ad0: 3b 0a 20 20 70 44 62 2d 3e 69 4d 6d 61 70 20 3d  ;.  pDb->iMmap =
0ae0: 20 4c 53 4d 5f 44 46 4c 54 5f 4d 4d 41 50 3b 0a   LSM_DFLT_MMAP;.
0af0: 20 20 70 44 62 2d 3e 78 4c 6f 67 20 3d 20 78 4c    pDb->xLog = xL
0b00: 6f 67 3b 0a 20 20 70 44 62 2d 3e 63 6f 6d 70 72  og;.  pDb->compr
0b10: 65 73 73 2e 69 49 64 20 3d 20 4c 53 4d 5f 43 4f  ess.iId = LSM_CO
0b20: 4d 50 52 45 53 53 49 4f 4e 5f 4e 4f 4e 45 3b 0a  MPRESSION_NONE;.
0b30: 20 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b    return LSM_OK;
0b40: 0a 7d 0a 0a 6c 73 6d 5f 65 6e 76 20 2a 6c 73 6d  .}..lsm_env *lsm
0b50: 5f 67 65 74 5f 65 6e 76 28 6c 73 6d 5f 64 62 20  _get_env(lsm_db 
0b60: 2a 70 44 62 29 7b 0a 20 20 61 73 73 65 72 74 28  *pDb){.  assert(
0b70: 20 70 44 62 2d 3e 70 45 6e 76 20 29 3b 0a 20 20   pDb->pEnv );.  
0b80: 72 65 74 75 72 6e 20 70 44 62 2d 3e 70 45 6e 76  return pDb->pEnv
0b90: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 64 61  ;.}../*.** If da
0ba0: 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 70 44  tabase handle pD
0bb0: 62 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 68  b is currently h
0bc0: 6f 6c 64 69 6e 67 20 61 20 63 6c 69 65 6e 74 20  olding a client 
0bd0: 73 6e 61 70 73 68 6f 74 2c 20 62 75 74 20 64 6f  snapshot, but do
0be0: 65 73 0a 2a 2a 20 6e 6f 74 20 68 61 76 65 20 61  es.** not have a
0bf0: 6e 79 20 6f 70 65 6e 20 63 75 72 73 6f 72 73 20  ny open cursors 
0c00: 6f 72 20 77 72 69 74 65 20 74 72 61 6e 73 61 63  or write transac
0c10: 74 69 6f 6e 73 2c 20 72 65 6c 65 61 73 65 20 69  tions, release i
0c20: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t..*/.static voi
0c30: 64 20 64 62 52 65 6c 65 61 73 65 43 6c 69 65 6e  d dbReleaseClien
0c40: 74 53 6e 61 70 73 68 6f 74 28 6c 73 6d 5f 64 62  tSnapshot(lsm_db
0c50: 20 2a 70 44 62 29 7b 0a 20 20 69 66 28 20 70 44   *pDb){.  if( pD
0c60: 62 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 3d 3d 30  b->nTransOpen==0
0c70: 20 26 26 20 70 44 62 2d 3e 70 43 73 72 3d 3d 30   && pDb->pCsr==0
0c80: 20 29 7b 0a 20 20 20 20 6c 73 6d 46 69 6e 69 73   ){.    lsmFinis
0c90: 68 52 65 61 64 54 72 61 6e 73 28 70 44 62 29 3b  hReadTrans(pDb);
0ca0: 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69  .  }.}..static i
0cb0: 6e 74 20 67 65 74 46 75 6c 6c 70 61 74 68 6e 61  nt getFullpathna
0cc0: 6d 65 28 0a 20 20 6c 73 6d 5f 65 6e 76 20 2a 70  me(.  lsm_env *p
0cd0: 45 6e 76 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68  Env, .  const ch
0ce0: 61 72 20 2a 7a 52 65 6c 2c 0a 20 20 63 68 61 72  ar *zRel,.  char
0cf0: 20 2a 2a 70 7a 41 62 73 0a 29 7b 0a 20 20 69 6e   **pzAbs.){.  in
0d00: 74 20 6e 41 6c 6c 6f 63 20 3d 20 30 3b 0a 20 20  t nAlloc = 0;.  
0d10: 63 68 61 72 20 2a 7a 41 6c 6c 6f 63 20 3d 20 30  char *zAlloc = 0
0d20: 3b 0a 20 20 69 6e 74 20 6e 52 65 71 20 3d 20 30  ;.  int nReq = 0
0d30: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 64  ;.  int rc;..  d
0d40: 6f 7b 0a 20 20 20 20 6e 41 6c 6c 6f 63 20 3d 20  o{.    nAlloc = 
0d50: 6e 52 65 71 3b 0a 20 20 20 20 72 63 20 3d 20 70  nReq;.    rc = p
0d60: 45 6e 76 2d 3e 78 46 75 6c 6c 70 61 74 68 28 70  Env->xFullpath(p
0d70: 45 6e 76 2c 20 7a 52 65 6c 2c 20 7a 41 6c 6c 6f  Env, zRel, zAllo
0d80: 63 2c 20 26 6e 52 65 71 29 3b 0a 20 20 20 20 69  c, &nReq);.    i
0d90: 66 28 20 6e 52 65 71 3e 6e 41 6c 6c 6f 63 20 29  f( nReq>nAlloc )
0da0: 7b 0a 20 20 20 20 20 20 7a 41 6c 6c 6f 63 20 3d  {.      zAlloc =
0db0: 20 6c 73 6d 52 65 61 6c 6c 6f 63 4f 72 46 72 65   lsmReallocOrFre
0dc0: 65 52 63 28 70 45 6e 76 2c 20 7a 41 6c 6c 6f 63  eRc(pEnv, zAlloc
0dd0: 2c 20 6e 52 65 71 2c 20 26 72 63 29 3b 0a 20 20  , nReq, &rc);.  
0de0: 20 20 7d 0a 20 20 7d 77 68 69 6c 65 28 20 6e 52    }.  }while( nR
0df0: 65 71 3e 6e 41 6c 6c 6f 63 20 26 26 20 72 63 3d  eq>nAlloc && rc=
0e00: 3d 4c 53 4d 5f 4f 4b 20 29 3b 0a 0a 20 20 69 66  =LSM_OK );..  if
0e10: 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a  ( rc!=LSM_OK ){.
0e20: 20 20 20 20 6c 73 6d 46 72 65 65 28 70 45 6e 76      lsmFree(pEnv
0e30: 2c 20 7a 41 6c 6c 6f 63 29 3b 0a 20 20 20 20 7a  , zAlloc);.    z
0e40: 41 6c 6c 6f 63 20 3d 20 30 3b 0a 20 20 7d 0a 20  Alloc = 0;.  }. 
0e50: 20 2a 70 7a 41 62 73 20 3d 20 7a 41 6c 6c 6f 63   *pzAbs = zAlloc
0e60: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
0e70: 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68  ../*.** Check th
0e80: 61 74 20 74 68 65 20 62 69 74 73 20 69 6e 20 74  at the bits in t
0e90: 68 65 20 64 62 2d 3e 6d 4c 6f 63 6b 20 6d 61 73  he db->mLock mas
0ea0: 6b 20 61 72 65 20 63 6f 6e 73 69 73 74 65 6e 74  k are consistent
0eb0: 20 77 69 74 68 20 74 68 65 0a 2a 2a 20 76 61 6c   with the.** val
0ec0: 75 65 20 73 74 6f 72 65 64 20 69 6e 20 64 62 2d  ue stored in db-
0ed0: 3e 69 52 77 63 6c 69 65 6e 74 2e 20 41 6e 20 61  >iRwclient. An a
0ee0: 73 73 65 72 74 20 73 68 61 6c 6c 20 66 61 69 6c  ssert shall fail
0ef0: 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73   otherwise..*/.s
0f00: 74 61 74 69 63 20 76 6f 69 64 20 61 73 73 65 72  tatic void asser
0f10: 74 52 77 63 6c 69 65 6e 74 4c 6f 63 6b 56 61 6c  tRwclientLockVal
0f20: 75 65 28 6c 73 6d 5f 64 62 20 2a 64 62 29 7b 0a  ue(lsm_db *db){.
0f30: 23 69 66 6e 64 65 66 20 4e 44 45 42 55 47 0a 20  #ifndef NDEBUG. 
0f40: 20 75 36 34 20 6d 73 6b 3b 20 20 20 20 20 20 20   u64 msk;       
0f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f60: 20 2f 2a 20 4d 61 73 6b 20 6f 66 20 6d 4c 6f 63   /* Mask of mLoc
0f70: 6b 20 62 69 74 73 20 66 6f 72 20 52 57 43 4c 49  k bits for RWCLI
0f80: 45 4e 54 20 6c 6f 63 6b 73 20 2a 2f 0a 20 20 75  ENT locks */.  u
0f90: 36 34 20 72 77 63 6c 69 65 6e 74 20 3d 20 30 3b  64 rwclient = 0;
0fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0fb0: 2a 20 42 69 74 20 63 6f 72 72 65 73 70 6f 6e 64  * Bit correspond
0fc0: 69 6e 67 20 74 6f 20 64 62 2d 3e 69 52 77 63 6c  ing to db->iRwcl
0fd0: 69 65 6e 74 20 2a 2f 0a 0a 20 20 69 66 28 20 64  ient */..  if( d
0fe0: 62 2d 3e 69 52 77 63 6c 69 65 6e 74 3e 3d 30 20  b->iRwclient>=0 
0ff0: 29 7b 0a 20 20 20 20 72 77 63 6c 69 65 6e 74 20  ){.    rwclient 
1000: 3d 20 28 28 75 36 34 29 31 20 3c 3c 20 28 4c 53  = ((u64)1 << (LS
1010: 4d 5f 4c 4f 43 4b 5f 52 57 43 4c 49 45 4e 54 28  M_LOCK_RWCLIENT(
1020: 64 62 2d 3e 69 52 77 63 6c 69 65 6e 74 29 2d 31  db->iRwclient)-1
1030: 29 29 3b 0a 20 20 7d 0a 20 20 6d 73 6b 20 20 3d  ));.  }.  msk  =
1040: 20 28 28 75 36 34 29 31 20 3c 3c 20 28 4c 53 4d   ((u64)1 << (LSM
1050: 5f 4c 4f 43 4b 5f 52 57 43 4c 49 45 4e 54 28 4c  _LOCK_RWCLIENT(L
1060: 53 4d 5f 4c 4f 43 4b 5f 4e 52 57 43 4c 49 45 4e  SM_LOCK_NRWCLIEN
1070: 54 29 2d 31 29 29 20 2d 20 31 3b 0a 20 20 6d 73  T)-1)) - 1;.  ms
1080: 6b 20 2d 3d 20 28 28 28 75 36 34 29 31 20 3c 3c  k -= (((u64)1 <<
1090: 20 28 4c 53 4d 5f 4c 4f 43 4b 5f 52 57 43 4c 49   (LSM_LOCK_RWCLI
10a0: 45 4e 54 28 30 29 2d 31 29 29 20 2d 20 31 29 3b  ENT(0)-1)) - 1);
10b0: 0a 0a 20 20 61 73 73 65 72 74 28 20 28 64 62 2d  ..  assert( (db-
10c0: 3e 6d 4c 6f 63 6b 20 26 20 6d 73 6b 29 3d 3d 72  >mLock & msk)==r
10d0: 77 63 6c 69 65 6e 74 20 29 3b 0a 23 65 6e 64 69  wclient );.#endi
10e0: 66 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20  f.}../*.** Open 
10f0: 61 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f 6e  a new connection
1100: 20 74 6f 20 64 61 74 61 62 61 73 65 20 7a 46 69   to database zFi
1110: 6c 65 6e 61 6d 65 2e 0a 2a 2f 0a 69 6e 74 20 6c  lename..*/.int l
1120: 73 6d 5f 6f 70 65 6e 28 6c 73 6d 5f 64 62 20 2a  sm_open(lsm_db *
1130: 70 44 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  pDb, const char 
1140: 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 69  *zFilename){.  i
1150: 6e 74 20 72 63 3b 0a 0a 20 20 69 66 28 20 70 44  nt rc;..  if( pD
1160: 62 2d 3e 70 44 61 74 61 62 61 73 65 20 29 7b 0a  b->pDatabase ){.
1170: 20 20 20 20 72 63 20 3d 20 4c 53 4d 5f 4d 49 53      rc = LSM_MIS
1180: 55 53 45 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  USE;.  }else{.  
1190: 20 20 63 68 61 72 20 2a 7a 46 75 6c 6c 3b 0a 0a    char *zFull;..
11a0: 20 20 20 20 2f 2a 20 54 72 61 6e 73 6c 61 74 65      /* Translate
11b0: 20 74 68 65 20 70 6f 73 73 69 62 6c 79 20 72 65   the possibly re
11c0: 6c 61 74 69 76 65 20 70 61 74 68 6e 61 6d 65 20  lative pathname 
11d0: 73 75 70 70 6c 69 65 64 20 62 79 20 74 68 65 20  supplied by the 
11e0: 75 73 65 72 20 69 6e 74 6f 0a 20 20 20 20 2a 2a  user into.    **
11f0: 20 61 6e 20 61 62 73 6f 6c 75 74 65 20 70 61 74   an absolute pat
1200: 68 6e 61 6d 65 2e 20 54 68 69 73 20 69 73 20 72  hname. This is r
1210: 65 71 75 69 72 65 64 20 62 65 63 61 75 73 65 20  equired because 
1220: 74 68 65 20 73 75 70 70 6c 69 65 64 20 70 61 74  the supplied pat
1230: 68 0a 20 20 20 20 2a 2a 20 69 73 20 75 73 65 64  h.    ** is used
1240: 20 28 65 69 74 68 65 72 20 64 69 72 65 63 74 6c   (either directl
1250: 79 20 6f 72 20 77 69 74 68 20 22 2d 6c 6f 67 22  y or with "-log"
1260: 20 61 70 70 65 6e 64 65 64 20 74 6f 20 69 74 29   appended to it)
1270: 20 66 6f 72 20 6d 6f 72 65 20 0a 20 20 20 20 2a   for more .    *
1280: 2a 20 74 68 61 6e 20 6f 6e 65 20 70 75 72 70 6f  * than one purpo
1290: 73 65 20 2d 20 74 6f 20 6f 70 65 6e 20 62 6f 74  se - to open bot
12a0: 68 20 74 68 65 20 64 61 74 61 62 61 73 65 20 61  h the database a
12b0: 6e 64 20 6c 6f 67 20 66 69 6c 65 73 2c 20 61 6e  nd log files, an
12c0: 64 20 0a 20 20 20 20 2a 2a 20 70 65 72 68 61 70  d .    ** perhap
12d0: 73 20 74 6f 20 75 6e 6c 69 6e 6b 20 74 68 65 20  s to unlink the 
12e0: 6c 6f 67 20 66 69 6c 65 20 64 75 72 69 6e 67 20  log file during 
12f0: 64 69 73 63 6f 6e 6e 65 63 74 69 6f 6e 2e 20 41  disconnection. A
1300: 6e 20 61 62 73 6f 6c 75 74 65 0a 20 20 20 20 2a  n absolute.    *
1310: 2a 20 70 61 74 68 20 69 73 20 72 65 71 75 69 72  * path is requir
1320: 65 64 20 74 6f 20 65 6e 73 75 72 65 20 74 68 61  ed to ensure tha
1330: 74 20 74 68 65 20 63 6f 72 72 65 63 74 20 66 69  t the correct fi
1340: 6c 65 73 20 61 72 65 20 6f 70 65 72 61 74 65 64  les are operated
1350: 0a 20 20 20 20 2a 2a 20 6f 6e 20 65 76 65 6e 20  .    ** on even 
1360: 69 66 20 74 68 65 20 61 70 70 6c 69 63 61 74 69  if the applicati
1370: 6f 6e 20 63 68 61 6e 67 65 73 20 74 68 65 20 63  on changes the c
1380: 77 64 2e 20 20 2a 2f 0a 20 20 20 20 72 63 20 3d  wd.  */.    rc =
1390: 20 67 65 74 46 75 6c 6c 70 61 74 68 6e 61 6d 65   getFullpathname
13a0: 28 70 44 62 2d 3e 70 45 6e 76 2c 20 7a 46 69 6c  (pDb->pEnv, zFil
13b0: 65 6e 61 6d 65 2c 20 26 7a 46 75 6c 6c 29 3b 0a  ename, &zFull);.
13c0: 20 20 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d      assert( rc==
13d0: 4c 53 4d 5f 4f 4b 20 7c 7c 20 7a 46 75 6c 6c 3d  LSM_OK || zFull=
13e0: 3d 30 20 29 3b 0a 0a 20 20 20 20 2f 2a 20 43 6f  =0 );..    /* Co
13f0: 6e 6e 65 63 74 20 74 6f 20 74 68 65 20 64 61 74  nnect to the dat
1400: 61 62 61 73 65 2e 20 2a 2f 0a 20 20 20 20 69 66  abase. */.    if
1410: 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a  ( rc==LSM_OK ){.
1420: 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 44 62        rc = lsmDb
1430: 44 61 74 61 62 61 73 65 43 6f 6e 6e 65 63 74 28  DatabaseConnect(
1440: 70 44 62 2c 20 7a 46 75 6c 6c 29 3b 0a 20 20 20  pDb, zFull);.   
1450: 20 7d 0a 0a 20 20 20 20 69 66 28 20 70 44 62 2d   }..    if( pDb-
1460: 3e 62 52 65 61 64 6f 6e 6c 79 3d 3d 30 20 29 7b  >bReadonly==0 ){
1470: 0a 20 20 20 20 20 20 2f 2a 20 43 6f 6e 66 69 67  .      /* Config
1480: 75 72 65 20 74 68 65 20 66 69 6c 65 2d 73 79 73  ure the file-sys
1490: 74 65 6d 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 77  tem connection w
14a0: 69 74 68 20 74 68 65 20 70 61 67 65 2d 73 69 7a  ith the page-siz
14b0: 65 20 61 6e 64 20 62 6c 6f 63 6b 2d 73 69 7a 65  e and block-size
14c0: 0a 20 20 20 20 20 20 2a 2a 20 6f 66 20 74 68 69  .      ** of thi
14d0: 73 20 64 61 74 61 62 61 73 65 2e 20 45 76 65 6e  s database. Even
14e0: 20 69 66 20 74 68 65 20 64 61 74 61 62 61 73 65   if the database
14f0: 20 66 69 6c 65 20 69 73 20 7a 65 72 6f 20 62 79   file is zero by
1500: 74 65 73 20 69 6e 20 73 69 7a 65 0a 20 20 20 20  tes in size.    
1510: 20 20 2a 2a 20 6f 6e 20 64 69 73 6b 2c 20 74 68    ** on disk, th
1520: 65 73 65 20 76 61 6c 75 65 73 20 68 61 76 65 20  ese values have 
1530: 62 65 65 6e 20 73 65 74 20 69 6e 20 73 68 61 72  been set in shar
1540: 65 64 2d 6d 65 6d 6f 72 79 20 62 79 20 6e 6f 77  ed-memory by now
1550: 2c 20 61 6e 64 20 73 6f 20 0a 20 20 20 20 20 20  , and so .      
1560: 2a 2a 20 61 72 65 20 67 75 61 72 61 6e 74 65 65  ** are guarantee
1570: 64 20 6e 6f 74 20 74 6f 20 63 68 61 6e 67 65 20  d not to change 
1580: 64 75 72 69 6e 67 20 74 68 65 20 6c 69 66 65 74  during the lifet
1590: 69 6d 65 20 6f 66 20 74 68 69 73 20 63 6f 6e 6e  ime of this conn
15a0: 65 63 74 69 6f 6e 2e 20 20 0a 20 20 20 20 20 20  ection.  .      
15b0: 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  */.      if( rc=
15c0: 3d 4c 53 4d 5f 4f 4b 20 26 26 20 4c 53 4d 5f 4f  =LSM_OK && LSM_O
15d0: 4b 3d 3d 28 72 63 20 3d 20 6c 73 6d 43 68 65 63  K==(rc = lsmChec
15e0: 6b 70 6f 69 6e 74 4c 6f 61 64 28 70 44 62 2c 20  kpointLoad(pDb, 
15f0: 30 29 29 20 29 7b 0a 20 20 20 20 20 20 20 20 6c  0)) ){.        l
1600: 73 6d 46 73 53 65 74 50 61 67 65 53 69 7a 65 28  smFsSetPageSize(
1610: 70 44 62 2d 3e 70 46 53 2c 20 6c 73 6d 43 68 65  pDb->pFS, lsmChe
1620: 63 6b 70 6f 69 6e 74 50 67 73 7a 28 70 44 62 2d  ckpointPgsz(pDb-
1630: 3e 61 53 6e 61 70 73 68 6f 74 29 29 3b 0a 20 20  >aSnapshot));.  
1640: 20 20 20 20 20 20 6c 73 6d 46 73 53 65 74 42 6c        lsmFsSetBl
1650: 6f 63 6b 53 69 7a 65 28 70 44 62 2d 3e 70 46 53  ockSize(pDb->pFS
1660: 2c 20 6c 73 6d 43 68 65 63 6b 70 6f 69 6e 74 42  , lsmCheckpointB
1670: 6c 6b 73 7a 28 70 44 62 2d 3e 61 53 6e 61 70 73  lksz(pDb->aSnaps
1680: 68 6f 74 29 29 3b 0a 20 20 20 20 20 20 7d 0a 20  hot));.      }. 
1690: 20 20 20 7d 0a 0a 20 20 20 20 6c 73 6d 46 72 65     }..    lsmFre
16a0: 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 7a 46 75  e(pDb->pEnv, zFu
16b0: 6c 6c 29 3b 0a 20 20 20 20 61 73 73 65 72 74 52  ll);.    assertR
16c0: 77 63 6c 69 65 6e 74 4c 6f 63 6b 56 61 6c 75 65  wclientLockValue
16d0: 28 70 44 62 29 3b 0a 20 20 7d 0a 0a 20 20 61 73  (pDb);.  }..  as
16e0: 73 65 72 74 28 20 70 44 62 2d 3e 62 52 65 61 64  sert( pDb->bRead
16f0: 6f 6e 6c 79 3d 3d 30 20 7c 7c 20 70 44 62 2d 3e  only==0 || pDb->
1700: 62 52 65 61 64 6f 6e 6c 79 3d 3d 31 20 29 3b 0a  bReadonly==1 );.
1710: 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 4c 53    assert( rc!=LS
1720: 4d 5f 4f 4b 20 7c 7c 20 28 70 44 62 2d 3e 70 53  M_OK || (pDb->pS
1730: 68 6d 68 64 72 3d 3d 30 29 3d 3d 28 70 44 62 2d  hmhdr==0)==(pDb-
1740: 3e 62 52 65 61 64 6f 6e 6c 79 3d 3d 31 29 20 29  >bReadonly==1) )
1750: 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  ;..  return rc;.
1760: 7d 0a 0a 69 6e 74 20 6c 73 6d 5f 63 6c 6f 73 65  }..int lsm_close
1770: 28 6c 73 6d 5f 64 62 20 2a 70 44 62 29 7b 0a 20  (lsm_db *pDb){. 
1780: 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
1790: 3b 0a 20 20 69 66 28 20 70 44 62 20 29 7b 0a 20  ;.  if( pDb ){. 
17a0: 20 20 20 61 73 73 65 72 74 5f 64 62 5f 73 74 61     assert_db_sta
17b0: 74 65 28 70 44 62 29 3b 0a 20 20 20 20 69 66 28  te(pDb);.    if(
17c0: 20 70 44 62 2d 3e 70 43 73 72 20 7c 7c 20 70 44   pDb->pCsr || pD
17d0: 62 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 20 29 7b  b->nTransOpen ){
17e0: 0a 20 20 20 20 20 20 72 63 20 3d 20 4c 53 4d 5f  .      rc = LSM_
17f0: 4d 49 53 55 53 45 5f 42 4b 50 54 3b 0a 20 20 20  MISUSE_BKPT;.   
1800: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6c 73   }else{.      ls
1810: 6d 4d 43 75 72 73 6f 72 46 72 65 65 43 61 63 68  mMCursorFreeCach
1820: 65 28 70 44 62 29 3b 0a 20 20 20 20 20 20 6c 73  e(pDb);.      ls
1830: 6d 46 72 65 65 53 6e 61 70 73 68 6f 74 28 70 44  mFreeSnapshot(pD
1840: 62 2d 3e 70 45 6e 76 2c 20 70 44 62 2d 3e 70 43  b->pEnv, pDb->pC
1850: 6c 69 65 6e 74 29 3b 0a 20 20 20 20 20 20 70 44  lient);.      pD
1860: 62 2d 3e 70 43 6c 69 65 6e 74 20 3d 20 30 3b 0a  b->pClient = 0;.
1870: 0a 20 20 20 20 20 20 61 73 73 65 72 74 52 77 63  .      assertRwc
1880: 6c 69 65 6e 74 4c 6f 63 6b 56 61 6c 75 65 28 70  lientLockValue(p
1890: 44 62 29 3b 0a 0a 20 20 20 20 20 20 6c 73 6d 44  Db);..      lsmD
18a0: 62 44 61 74 61 62 61 73 65 52 65 6c 65 61 73 65  bDatabaseRelease
18b0: 28 70 44 62 29 3b 0a 20 20 20 20 20 20 6c 73 6d  (pDb);.      lsm
18c0: 4c 6f 67 43 6c 6f 73 65 28 70 44 62 29 3b 0a 20  LogClose(pDb);. 
18d0: 20 20 20 20 20 6c 73 6d 46 73 43 6c 6f 73 65 28       lsmFsClose(
18e0: 70 44 62 2d 3e 70 46 53 29 3b 0a 20 20 20 20 20  pDb->pFS);.     
18f0: 20 2f 2a 20 61 73 73 65 72 74 28 20 70 44 62 2d   /* assert( pDb-
1900: 3e 6d 4c 6f 63 6b 3d 3d 30 20 29 3b 20 2a 2f 0a  >mLock==0 ); */.
1910: 20 20 20 20 20 20 0a 20 20 20 20 20 20 2f 2a 20        .      /* 
1920: 49 6e 76 6f 6b 65 20 61 6e 79 20 64 65 73 74 72  Invoke any destr
1930: 75 63 74 6f 72 73 20 72 65 67 69 73 74 65 72 65  uctors registere
1940: 64 20 66 6f 72 20 74 68 65 20 63 6f 6d 70 72 65  d for the compre
1950: 73 73 69 6f 6e 20 6f 72 20 0a 20 20 20 20 20 20  ssion or .      
1960: 2a 2a 20 63 6f 6d 70 72 65 73 73 69 6f 6e 20 66  ** compression f
1970: 61 63 74 6f 72 79 20 63 61 6c 6c 62 61 63 6b 73  actory callbacks
1980: 2e 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20  .  */.      if( 
1990: 70 44 62 2d 3e 66 61 63 74 6f 72 79 2e 78 46 72  pDb->factory.xFr
19a0: 65 65 20 29 20 70 44 62 2d 3e 66 61 63 74 6f 72  ee ) pDb->factor
19b0: 79 2e 78 46 72 65 65 28 70 44 62 2d 3e 66 61 63  y.xFree(pDb->fac
19c0: 74 6f 72 79 2e 70 43 74 78 29 3b 0a 20 20 20 20  tory.pCtx);.    
19d0: 20 20 69 66 28 20 70 44 62 2d 3e 63 6f 6d 70 72    if( pDb->compr
19e0: 65 73 73 2e 78 46 72 65 65 20 29 20 70 44 62 2d  ess.xFree ) pDb-
19f0: 3e 63 6f 6d 70 72 65 73 73 2e 78 46 72 65 65 28  >compress.xFree(
1a00: 70 44 62 2d 3e 63 6f 6d 70 72 65 73 73 2e 70 43  pDb->compress.pC
1a10: 74 78 29 3b 0a 0a 20 20 20 20 20 20 6c 73 6d 46  tx);..      lsmF
1a20: 72 65 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70  ree(pDb->pEnv, p
1a30: 44 62 2d 3e 72 6f 6c 6c 62 61 63 6b 2e 61 41 72  Db->rollback.aAr
1a40: 72 61 79 29 3b 0a 20 20 20 20 20 20 6c 73 6d 46  ray);.      lsmF
1a50: 72 65 65 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70  ree(pDb->pEnv, p
1a60: 44 62 2d 3e 61 54 72 61 6e 73 29 3b 0a 20 20 20  Db->aTrans);.   
1a70: 20 20 20 6c 73 6d 46 72 65 65 28 70 44 62 2d 3e     lsmFree(pDb->
1a80: 70 45 6e 76 2c 20 70 44 62 2d 3e 61 70 53 68 6d  pEnv, pDb->apShm
1a90: 29 3b 0a 20 20 20 20 20 20 6c 73 6d 46 72 65 65  );.      lsmFree
1aa0: 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70 44 62 29  (pDb->pEnv, pDb)
1ab0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  ;.    }.  }.  re
1ac0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20  turn rc;.}..int 
1ad0: 6c 73 6d 5f 63 6f 6e 66 69 67 28 6c 73 6d 5f 64  lsm_config(lsm_d
1ae0: 62 20 2a 70 44 62 2c 20 69 6e 74 20 65 50 61 72  b *pDb, int ePar
1af0: 61 6d 2c 20 2e 2e 2e 29 7b 0a 20 20 69 6e 74 20  am, ...){.  int 
1b00: 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 76  rc = LSM_OK;.  v
1b10: 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 5f  a_list ap;.  va_
1b20: 73 74 61 72 74 28 61 70 2c 20 65 50 61 72 61 6d  start(ap, eParam
1b30: 29 3b 0a 0a 20 20 73 77 69 74 63 68 28 20 65 50  );..  switch( eP
1b40: 61 72 61 6d 20 29 7b 0a 20 20 20 20 63 61 73 65  aram ){.    case
1b50: 20 4c 53 4d 5f 43 4f 4e 46 49 47 5f 41 55 54 4f   LSM_CONFIG_AUTO
1b60: 46 4c 55 53 48 3a 20 7b 0a 20 20 20 20 20 20 2f  FLUSH: {.      /
1b70: 2a 20 54 68 69 73 20 70 61 72 61 6d 65 74 65 72  * This parameter
1b80: 20 69 73 20 72 65 61 64 20 61 6e 64 20 77 72 69   is read and wri
1b90: 74 74 65 6e 20 69 6e 20 4b 42 2e 20 42 75 74 20  tten in KB. But 
1ba0: 61 6c 6c 20 69 6e 74 65 72 6e 61 6c 20 0a 20 20  all internal .  
1bb0: 20 20 20 20 2a 2a 20 70 72 6f 63 65 73 73 69 6e      ** processin
1bc0: 67 20 69 73 20 64 6f 6e 65 20 69 6e 20 62 79 74  g is done in byt
1bd0: 65 73 2e 20 20 2a 2f 0a 20 20 20 20 20 20 69 6e  es.  */.      in
1be0: 74 20 2a 70 69 56 61 6c 20 3d 20 76 61 5f 61 72  t *piVal = va_ar
1bf0: 67 28 61 70 2c 20 69 6e 74 20 2a 29 3b 0a 20 20  g(ap, int *);.  
1c00: 20 20 20 20 69 6e 74 20 69 56 61 6c 20 3d 20 2a      int iVal = *
1c10: 70 69 56 61 6c 3b 0a 20 20 20 20 20 20 69 66 28  piVal;.      if(
1c20: 20 69 56 61 6c 3e 3d 30 20 26 26 20 69 56 61 6c   iVal>=0 && iVal
1c30: 3c 3d 28 31 30 32 34 2a 31 30 32 34 29 20 29 7b  <=(1024*1024) ){
1c40: 0a 20 20 20 20 20 20 20 20 70 44 62 2d 3e 6e 54  .        pDb->nT
1c50: 72 65 65 4c 69 6d 69 74 20 3d 20 69 56 61 6c 2a  reeLimit = iVal*
1c60: 31 30 32 34 3b 0a 20 20 20 20 20 20 7d 0a 20 20  1024;.      }.  
1c70: 20 20 20 20 2a 70 69 56 61 6c 20 3d 20 28 70 44      *piVal = (pD
1c80: 62 2d 3e 6e 54 72 65 65 4c 69 6d 69 74 20 2f 20  b->nTreeLimit / 
1c90: 31 30 32 34 29 3b 0a 20 20 20 20 20 20 62 72 65  1024);.      bre
1ca0: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
1cb0: 61 73 65 20 4c 53 4d 5f 43 4f 4e 46 49 47 5f 41  ase LSM_CONFIG_A
1cc0: 55 54 4f 57 4f 52 4b 3a 20 7b 0a 20 20 20 20 20  UTOWORK: {.     
1cd0: 20 69 6e 74 20 2a 70 69 56 61 6c 20 3d 20 76 61   int *piVal = va
1ce0: 5f 61 72 67 28 61 70 2c 20 69 6e 74 20 2a 29 3b  _arg(ap, int *);
1cf0: 0a 20 20 20 20 20 20 69 66 28 20 2a 70 69 56 61  .      if( *piVa
1d00: 6c 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  l>=0 ){.        
1d10: 70 44 62 2d 3e 62 41 75 74 6f 77 6f 72 6b 20 3d  pDb->bAutowork =
1d20: 20 2a 70 69 56 61 6c 3b 0a 20 20 20 20 20 20 7d   *piVal;.      }
1d30: 0a 20 20 20 20 20 20 2a 70 69 56 61 6c 20 3d 20  .      *piVal = 
1d40: 70 44 62 2d 3e 62 41 75 74 6f 77 6f 72 6b 3b 0a  pDb->bAutowork;.
1d50: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
1d60: 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 4c 53 4d   }..    case LSM
1d70: 5f 43 4f 4e 46 49 47 5f 41 55 54 4f 43 48 45 43  _CONFIG_AUTOCHEC
1d80: 4b 50 4f 49 4e 54 3a 20 7b 0a 20 20 20 20 20 20  KPOINT: {.      
1d90: 2f 2a 20 54 68 69 73 20 70 61 72 61 6d 65 74 65  /* This paramete
1da0: 72 20 69 73 20 72 65 61 64 20 61 6e 64 20 77 72  r is read and wr
1db0: 69 74 74 65 6e 20 69 6e 20 4b 42 2e 20 42 75 74  itten in KB. But
1dc0: 20 61 6c 6c 20 69 6e 74 65 72 6e 61 6c 20 70 72   all internal pr
1dd0: 6f 63 65 73 73 69 6e 67 0a 20 20 20 20 20 20 2a  ocessing.      *
1de0: 2a 20 28 69 6e 63 6c 75 64 69 6e 67 20 74 68 65  * (including the
1df0: 20 6c 73 6d 5f 64 62 2e 6e 41 75 74 6f 63 6b 70   lsm_db.nAutockp
1e00: 74 20 76 61 72 69 61 62 6c 65 29 20 69 73 20 64  t variable) is d
1e10: 6f 6e 65 20 69 6e 20 62 79 74 65 73 2e 20 20 2a  one in bytes.  *
1e20: 2f 0a 20 20 20 20 20 20 69 6e 74 20 2a 70 69 56  /.      int *piV
1e30: 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20  al = va_arg(ap, 
1e40: 69 6e 74 20 2a 29 3b 0a 20 20 20 20 20 20 69 66  int *);.      if
1e50: 28 20 2a 70 69 56 61 6c 3e 3d 30 20 29 7b 0a 20  ( *piVal>=0 ){. 
1e60: 20 20 20 20 20 20 20 69 6e 74 20 69 56 61 6c 20         int iVal 
1e70: 3d 20 2a 70 69 56 61 6c 3b 0a 20 20 20 20 20 20  = *piVal;.      
1e80: 20 20 70 44 62 2d 3e 6e 41 75 74 6f 63 6b 70 74    pDb->nAutockpt
1e90: 20 3d 20 28 69 36 34 29 69 56 61 6c 20 2a 20 31   = (i64)iVal * 1
1ea0: 30 32 34 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  024;.      }.   
1eb0: 20 20 20 2a 70 69 56 61 6c 20 3d 20 28 69 6e 74     *piVal = (int
1ec0: 29 28 70 44 62 2d 3e 6e 41 75 74 6f 63 6b 70 74  )(pDb->nAutockpt
1ed0: 20 2f 20 31 30 32 34 29 3b 0a 20 20 20 20 20 20   / 1024);.      
1ee0: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
1ef0: 20 20 63 61 73 65 20 4c 53 4d 5f 43 4f 4e 46 49    case LSM_CONFI
1f00: 47 5f 50 41 47 45 5f 53 49 5a 45 3a 20 7b 0a 20  G_PAGE_SIZE: {. 
1f10: 20 20 20 20 20 69 6e 74 20 2a 70 69 56 61 6c 20       int *piVal 
1f20: 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 69 6e 74  = va_arg(ap, int
1f30: 20 2a 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70   *);.      if( p
1f40: 44 62 2d 3e 70 44 61 74 61 62 61 73 65 20 29 7b  Db->pDatabase ){
1f50: 0a 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 6c  .        /* If l
1f60: 73 6d 5f 6f 70 65 6e 28 29 20 68 61 73 20 62 65  sm_open() has be
1f70: 65 6e 20 63 61 6c 6c 65 64 2c 20 74 68 69 73 20  en called, this 
1f80: 69 73 20 61 20 72 65 61 64 2d 6f 6e 6c 79 20 70  is a read-only p
1f90: 61 72 61 6d 65 74 65 72 2e 20 0a 20 20 20 20 20  arameter. .     
1fa0: 20 20 20 2a 2a 20 53 65 74 20 74 68 65 20 6f 75     ** Set the ou
1fb0: 74 70 75 74 20 76 61 72 69 61 62 6c 65 20 74 6f  tput variable to
1fc0: 20 74 68 65 20 70 61 67 65 2d 73 69 7a 65 20 61   the page-size a
1fd0: 63 63 6f 72 64 69 6e 67 20 74 6f 20 74 68 65 20  ccording to the 
1fe0: 0a 20 20 20 20 20 20 20 20 2a 2a 20 46 69 6c 65  .        ** File
1ff0: 53 79 73 74 65 6d 20 6f 62 6a 65 63 74 2e 20 20  System object.  
2000: 2a 2f 0a 20 20 20 20 20 20 20 20 2a 70 69 56 61  */.        *piVa
2010: 6c 20 3d 20 6c 73 6d 46 73 50 61 67 65 53 69 7a  l = lsmFsPageSiz
2020: 65 28 70 44 62 2d 3e 70 46 53 29 3b 0a 20 20 20  e(pDb->pFS);.   
2030: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
2040: 20 20 69 66 28 20 2a 70 69 56 61 6c 3e 3d 32 35    if( *piVal>=25
2050: 36 20 26 26 20 2a 70 69 56 61 6c 3c 3d 36 35 35  6 && *piVal<=655
2060: 33 36 20 26 26 20 28 28 2a 70 69 56 61 6c 2d 31  36 && ((*piVal-1
2070: 29 20 26 20 2a 70 69 56 61 6c 29 3d 3d 30 20 29  ) & *piVal)==0 )
2080: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 44 62 2d  {.          pDb-
2090: 3e 6e 44 66 6c 74 50 67 73 7a 20 3d 20 2a 70 69  >nDfltPgsz = *pi
20a0: 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  Val;.        }el
20b0: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 2a 70  se{.          *p
20c0: 69 56 61 6c 20 3d 20 70 44 62 2d 3e 6e 44 66 6c  iVal = pDb->nDfl
20d0: 74 50 67 73 7a 3b 0a 20 20 20 20 20 20 20 20 7d  tPgsz;.        }
20e0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62  .      }.      b
20f0: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  reak;.    }..   
2100: 20 63 61 73 65 20 4c 53 4d 5f 43 4f 4e 46 49 47   case LSM_CONFIG
2110: 5f 42 4c 4f 43 4b 5f 53 49 5a 45 3a 20 7b 0a 20  _BLOCK_SIZE: {. 
2120: 20 20 20 20 20 2f 2a 20 54 68 69 73 20 70 61 72       /* This par
2130: 61 6d 65 74 65 72 20 69 73 20 72 65 61 64 20 61  ameter is read a
2140: 6e 64 20 77 72 69 74 74 65 6e 20 69 6e 20 4b 42  nd written in KB
2150: 2e 20 42 75 74 20 61 6c 6c 20 69 6e 74 65 72 6e  . But all intern
2160: 61 6c 20 0a 20 20 20 20 20 20 2a 2a 20 70 72 6f  al .      ** pro
2170: 63 65 73 73 69 6e 67 20 69 73 20 64 6f 6e 65 20  cessing is done 
2180: 69 6e 20 62 79 74 65 73 2e 20 20 2a 2f 0a 20 20  in bytes.  */.  
2190: 20 20 20 20 69 6e 74 20 2a 70 69 56 61 6c 20 3d      int *piVal =
21a0: 20 76 61 5f 61 72 67 28 61 70 2c 20 69 6e 74 20   va_arg(ap, int 
21b0: 2a 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 44  *);.      if( pD
21c0: 62 2d 3e 70 44 61 74 61 62 61 73 65 20 29 7b 0a  b->pDatabase ){.
21d0: 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 6c 73          /* If ls
21e0: 6d 5f 6f 70 65 6e 28 29 20 68 61 73 20 62 65 65  m_open() has bee
21f0: 6e 20 63 61 6c 6c 65 64 2c 20 74 68 69 73 20 69  n called, this i
2200: 73 20 61 20 72 65 61 64 2d 6f 6e 6c 79 20 70 61  s a read-only pa
2210: 72 61 6d 65 74 65 72 2e 20 0a 20 20 20 20 20 20  rameter. .      
2220: 20 20 2a 2a 20 53 65 74 20 74 68 65 20 6f 75 74    ** Set the out
2230: 70 75 74 20 76 61 72 69 61 62 6c 65 20 74 6f 20  put variable to 
2240: 74 68 65 20 62 6c 6f 63 6b 2d 73 69 7a 65 20 69  the block-size i
2250: 6e 20 4b 42 20 61 63 63 6f 72 64 69 6e 67 20 74  n KB according t
2260: 6f 20 74 68 65 20 0a 20 20 20 20 20 20 20 20 2a  o the .        *
2270: 2a 20 46 69 6c 65 53 79 73 74 65 6d 20 6f 62 6a  * FileSystem obj
2280: 65 63 74 2e 20 20 2a 2f 0a 20 20 20 20 20 20 20  ect.  */.       
2290: 20 2a 70 69 56 61 6c 20 3d 20 6c 73 6d 46 73 42   *piVal = lsmFsB
22a0: 6c 6f 63 6b 53 69 7a 65 28 70 44 62 2d 3e 70 46  lockSize(pDb->pF
22b0: 53 29 20 2f 20 31 30 32 34 3b 0a 20 20 20 20 20  S) / 1024;.     
22c0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
22d0: 69 6e 74 20 69 56 61 6c 20 3d 20 2a 70 69 56 61  int iVal = *piVa
22e0: 6c 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 69  l;.        if( i
22f0: 56 61 6c 3e 3d 36 34 20 26 26 20 69 56 61 6c 3c  Val>=64 && iVal<
2300: 3d 36 35 35 33 36 20 26 26 20 28 28 69 56 61 6c  =65536 && ((iVal
2310: 2d 31 29 20 26 20 69 56 61 6c 29 3d 3d 30 20 29  -1) & iVal)==0 )
2320: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 44 62 2d  {.          pDb-
2330: 3e 6e 44 66 6c 74 42 6c 6b 73 7a 20 3d 20 69 56  >nDfltBlksz = iV
2340: 61 6c 20 2a 20 31 30 32 34 3b 0a 20 20 20 20 20  al * 1024;.     
2350: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
2360: 20 20 20 20 2a 70 69 56 61 6c 20 3d 20 70 44 62      *piVal = pDb
2370: 2d 3e 6e 44 66 6c 74 42 6c 6b 73 7a 20 2f 20 31  ->nDfltBlksz / 1
2380: 30 32 34 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  024;.        }. 
2390: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65       }.      bre
23a0: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
23b0: 61 73 65 20 4c 53 4d 5f 43 4f 4e 46 49 47 5f 53  ase LSM_CONFIG_S
23c0: 41 46 45 54 59 3a 20 7b 0a 20 20 20 20 20 20 69  AFETY: {.      i
23d0: 6e 74 20 2a 70 69 56 61 6c 20 3d 20 76 61 5f 61  nt *piVal = va_a
23e0: 72 67 28 61 70 2c 20 69 6e 74 20 2a 29 3b 0a 20  rg(ap, int *);. 
23f0: 20 20 20 20 20 69 66 28 20 2a 70 69 56 61 6c 3e       if( *piVal>
2400: 3d 30 20 26 26 20 2a 70 69 56 61 6c 3c 3d 32 20  =0 && *piVal<=2 
2410: 29 7b 0a 20 20 20 20 20 20 20 20 70 44 62 2d 3e  ){.        pDb->
2420: 65 53 61 66 65 74 79 20 3d 20 2a 70 69 56 61 6c  eSafety = *piVal
2430: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
2440: 2a 70 69 56 61 6c 20 3d 20 70 44 62 2d 3e 65 53  *piVal = pDb->eS
2450: 61 66 65 74 79 3b 0a 20 20 20 20 20 20 62 72 65  afety;.      bre
2460: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
2470: 61 73 65 20 4c 53 4d 5f 43 4f 4e 46 49 47 5f 4d  ase LSM_CONFIG_M
2480: 4d 41 50 3a 20 7b 0a 20 20 20 20 20 20 69 6e 74  MAP: {.      int
2490: 20 2a 70 69 56 61 6c 20 3d 20 76 61 5f 61 72 67   *piVal = va_arg
24a0: 28 61 70 2c 20 69 6e 74 20 2a 29 3b 0a 20 20 20  (ap, int *);.   
24b0: 20 20 20 69 66 28 20 70 44 62 2d 3e 69 52 65 61     if( pDb->iRea
24c0: 64 65 72 3c 30 20 26 26 20 2a 70 69 56 61 6c 3e  der<0 && *piVal>
24d0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 70 44  =0 ){.        pD
24e0: 62 2d 3e 69 4d 6d 61 70 20 3d 20 2a 70 69 56 61  b->iMmap = *piVa
24f0: 6c 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  l;.        rc = 
2500: 6c 73 6d 46 73 43 6f 6e 66 69 67 75 72 65 28 70  lsmFsConfigure(p
2510: 44 62 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  Db);.      }.   
2520: 20 20 20 2a 70 69 56 61 6c 20 3d 20 70 44 62 2d     *piVal = pDb-
2530: 3e 69 4d 6d 61 70 3b 0a 20 20 20 20 20 20 62 72  >iMmap;.      br
2540: 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  eak;.    }..    
2550: 63 61 73 65 20 4c 53 4d 5f 43 4f 4e 46 49 47 5f  case LSM_CONFIG_
2560: 55 53 45 5f 4c 4f 47 3a 20 7b 0a 20 20 20 20 20  USE_LOG: {.     
2570: 20 69 6e 74 20 2a 70 69 56 61 6c 20 3d 20 76 61   int *piVal = va
2580: 5f 61 72 67 28 61 70 2c 20 69 6e 74 20 2a 29 3b  _arg(ap, int *);
2590: 0a 20 20 20 20 20 20 69 66 28 20 70 44 62 2d 3e  .      if( pDb->
25a0: 6e 54 72 61 6e 73 4f 70 65 6e 3d 3d 30 20 26 26  nTransOpen==0 &&
25b0: 20 28 2a 70 69 56 61 6c 3d 3d 30 20 7c 7c 20 2a   (*piVal==0 || *
25c0: 70 69 56 61 6c 3d 3d 31 29 20 29 7b 0a 20 20 20  piVal==1) ){.   
25d0: 20 20 20 20 20 70 44 62 2d 3e 62 55 73 65 4c 6f       pDb->bUseLo
25e0: 67 20 3d 20 2a 70 69 56 61 6c 3b 0a 20 20 20 20  g = *piVal;.    
25f0: 20 20 7d 0a 20 20 20 20 20 20 2a 70 69 56 61 6c    }.      *piVal
2600: 20 3d 20 70 44 62 2d 3e 62 55 73 65 4c 6f 67 3b   = pDb->bUseLog;
2610: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
2620: 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 4c 53    }..    case LS
2630: 4d 5f 43 4f 4e 46 49 47 5f 41 55 54 4f 4d 45 52  M_CONFIG_AUTOMER
2640: 47 45 3a 20 7b 0a 20 20 20 20 20 20 69 6e 74 20  GE: {.      int 
2650: 2a 70 69 56 61 6c 20 3d 20 76 61 5f 61 72 67 28  *piVal = va_arg(
2660: 61 70 2c 20 69 6e 74 20 2a 29 3b 0a 20 20 20 20  ap, int *);.    
2670: 20 20 69 66 28 20 2a 70 69 56 61 6c 3e 31 20 29    if( *piVal>1 )
2680: 20 70 44 62 2d 3e 6e 4d 65 72 67 65 20 3d 20 2a   pDb->nMerge = *
2690: 70 69 56 61 6c 3b 0a 20 20 20 20 20 20 2a 70 69  piVal;.      *pi
26a0: 56 61 6c 20 3d 20 70 44 62 2d 3e 6e 4d 65 72 67  Val = pDb->nMerg
26b0: 65 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  e;.      break;.
26c0: 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20      }..    case 
26d0: 4c 53 4d 5f 43 4f 4e 46 49 47 5f 4d 41 58 5f 46  LSM_CONFIG_MAX_F
26e0: 52 45 45 4c 49 53 54 3a 20 7b 0a 20 20 20 20 20  REELIST: {.     
26f0: 20 69 6e 74 20 2a 70 69 56 61 6c 20 3d 20 76 61   int *piVal = va
2700: 5f 61 72 67 28 61 70 2c 20 69 6e 74 20 2a 29 3b  _arg(ap, int *);
2710: 0a 20 20 20 20 20 20 69 66 28 20 2a 70 69 56 61  .      if( *piVa
2720: 6c 3e 3d 32 20 26 26 20 2a 70 69 56 61 6c 3c 3d  l>=2 && *piVal<=
2730: 4c 53 4d 5f 4d 41 58 5f 46 52 45 45 4c 49 53 54  LSM_MAX_FREELIST
2740: 5f 45 4e 54 52 49 45 53 20 29 7b 0a 20 20 20 20  _ENTRIES ){.    
2750: 20 20 20 20 70 44 62 2d 3e 6e 4d 61 78 46 72 65      pDb->nMaxFre
2760: 65 6c 69 73 74 20 3d 20 2a 70 69 56 61 6c 3b 0a  elist = *piVal;.
2770: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 2a 70        }.      *p
2780: 69 56 61 6c 20 3d 20 70 44 62 2d 3e 6e 4d 61 78  iVal = pDb->nMax
2790: 46 72 65 65 6c 69 73 74 3b 0a 20 20 20 20 20 20  Freelist;.      
27a0: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
27b0: 20 20 63 61 73 65 20 4c 53 4d 5f 43 4f 4e 46 49    case LSM_CONFI
27c0: 47 5f 4d 55 4c 54 49 50 4c 45 5f 50 52 4f 43 45  G_MULTIPLE_PROCE
27d0: 53 53 45 53 3a 20 7b 0a 20 20 20 20 20 20 69 6e  SSES: {.      in
27e0: 74 20 2a 70 69 56 61 6c 20 3d 20 76 61 5f 61 72  t *piVal = va_ar
27f0: 67 28 61 70 2c 20 69 6e 74 20 2a 29 3b 0a 20 20  g(ap, int *);.  
2800: 20 20 20 20 69 66 28 20 70 44 62 2d 3e 70 44 61      if( pDb->pDa
2810: 74 61 62 61 73 65 20 29 7b 0a 20 20 20 20 20 20  tabase ){.      
2820: 20 20 2f 2a 20 49 66 20 6c 73 6d 5f 6f 70 65 6e    /* If lsm_open
2830: 28 29 20 68 61 73 20 62 65 65 6e 20 63 61 6c 6c  () has been call
2840: 65 64 2c 20 74 68 69 73 20 69 73 20 61 20 72 65  ed, this is a re
2850: 61 64 2d 6f 6e 6c 79 20 70 61 72 61 6d 65 74 65  ad-only paramete
2860: 72 2e 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 53  r. .        ** S
2870: 65 74 20 74 68 65 20 6f 75 74 70 75 74 20 76 61  et the output va
2880: 72 69 61 62 6c 65 20 74 6f 20 74 72 75 65 20 69  riable to true i
2890: 66 20 74 68 69 73 20 63 6f 6e 6e 65 63 74 69 6f  f this connectio
28a0: 6e 20 69 73 20 63 75 72 72 65 6e 74 6c 79 0a 20  n is currently. 
28b0: 20 20 20 20 20 20 20 2a 2a 20 69 6e 20 6d 75 6c         ** in mul
28c0: 74 69 2d 70 72 6f 63 65 73 73 20 6d 6f 64 65 2e  ti-process mode.
28d0: 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 2a 70 69    */.        *pi
28e0: 56 61 6c 20 3d 20 6c 73 6d 44 62 4d 75 6c 74 69  Val = lsmDbMulti
28f0: 50 72 6f 63 28 70 44 62 29 3b 0a 20 20 20 20 20  Proc(pDb);.     
2900: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
2910: 70 44 62 2d 3e 62 4d 75 6c 74 69 50 72 6f 63 20  pDb->bMultiProc 
2920: 3d 20 2a 70 69 56 61 6c 20 3d 20 28 2a 70 69 56  = *piVal = (*piV
2930: 61 6c 21 3d 30 29 3b 0a 20 20 20 20 20 20 7d 0a  al!=0);.      }.
2940: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
2950: 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 4c 53 4d   }..    case LSM
2960: 5f 43 4f 4e 46 49 47 5f 52 45 41 44 4f 4e 4c 59  _CONFIG_READONLY
2970: 3a 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 2a 70  : {.      int *p
2980: 69 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 70  iVal = va_arg(ap
2990: 2c 20 69 6e 74 20 2a 29 3b 0a 20 20 20 20 20 20  , int *);.      
29a0: 2f 2a 20 49 66 20 6c 73 6d 5f 6f 70 65 6e 28 29  /* If lsm_open()
29b0: 20 68 61 73 20 62 65 65 6e 20 63 61 6c 6c 65 64   has been called
29c0: 2c 20 74 68 69 73 20 69 73 20 61 20 72 65 61 64  , this is a read
29d0: 2d 6f 6e 6c 79 20 70 61 72 61 6d 65 74 65 72 2e  -only parameter.
29e0: 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 70 44   */.      if( pD
29f0: 62 2d 3e 70 44 61 74 61 62 61 73 65 3d 3d 30 20  b->pDatabase==0 
2a00: 26 26 20 2a 70 69 56 61 6c 3e 3d 30 20 29 7b 0a  && *piVal>=0 ){.
2a10: 20 20 20 20 20 20 20 20 70 44 62 2d 3e 62 52 65          pDb->bRe
2a20: 61 64 6f 6e 6c 79 20 3d 20 2a 70 69 56 61 6c 20  adonly = *piVal 
2a30: 3d 20 28 2a 70 69 56 61 6c 21 3d 30 29 3b 0a 20  = (*piVal!=0);. 
2a40: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 2a 70 69       }.      *pi
2a50: 56 61 6c 20 3d 20 70 44 62 2d 3e 62 52 65 61 64  Val = pDb->bRead
2a60: 6f 6e 6c 79 3b 0a 20 20 20 20 20 20 62 72 65 61  only;.      brea
2a70: 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61  k;.    }..    ca
2a80: 73 65 20 4c 53 4d 5f 43 4f 4e 46 49 47 5f 53 45  se LSM_CONFIG_SE
2a90: 54 5f 43 4f 4d 50 52 45 53 53 49 4f 4e 3a 20 7b  T_COMPRESSION: {
2aa0: 0a 20 20 20 20 20 20 6c 73 6d 5f 63 6f 6d 70 72  .      lsm_compr
2ab0: 65 73 73 20 2a 70 20 3d 20 76 61 5f 61 72 67 28  ess *p = va_arg(
2ac0: 61 70 2c 20 6c 73 6d 5f 63 6f 6d 70 72 65 73 73  ap, lsm_compress
2ad0: 20 2a 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70   *);.      if( p
2ae0: 44 62 2d 3e 69 52 65 61 64 65 72 3e 3d 30 20 26  Db->iReader>=0 &
2af0: 26 20 70 44 62 2d 3e 62 49 6e 46 61 63 74 6f 72  & pDb->bInFactor
2b00: 79 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  y==0 ){.        
2b10: 2f 2a 20 4d 61 79 20 6e 6f 74 20 63 68 61 6e 67  /* May not chang
2b20: 65 20 63 6f 6d 70 72 65 73 73 69 6f 6e 20 73 63  e compression sc
2b30: 68 65 6d 65 73 20 77 69 74 68 20 61 6e 20 6f 70  hemes with an op
2b40: 65 6e 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a  en transaction *
2b50: 2f 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 4c  /.        rc = L
2b60: 53 4d 5f 4d 49 53 55 53 45 5f 42 4b 50 54 3b 0a  SM_MISUSE_BKPT;.
2b70: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
2b80: 20 20 20 20 20 69 66 28 20 70 44 62 2d 3e 63 6f       if( pDb->co
2b90: 6d 70 72 65 73 73 2e 78 46 72 65 65 20 29 7b 0a  mpress.xFree ){.
2ba0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 76            /* Inv
2bb0: 6f 6b 65 20 61 6e 79 20 64 65 73 74 72 75 63 74  oke any destruct
2bc0: 6f 72 20 62 65 6c 6f 6e 67 69 6e 67 20 74 6f 20  or belonging to 
2bd0: 74 68 65 20 63 75 72 72 65 6e 74 20 63 6f 6d 70  the current comp
2be0: 72 65 73 73 69 6f 6e 2e 20 2a 2f 0a 20 20 20 20  ression. */.    
2bf0: 20 20 20 20 20 20 70 44 62 2d 3e 63 6f 6d 70 72        pDb->compr
2c00: 65 73 73 2e 78 46 72 65 65 28 70 44 62 2d 3e 63  ess.xFree(pDb->c
2c10: 6f 6d 70 72 65 73 73 2e 70 43 74 78 29 3b 0a 20  ompress.pCtx);. 
2c20: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
2c30: 20 69 66 28 20 70 2d 3e 78 42 6f 75 6e 64 3d 3d   if( p->xBound==
2c40: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d  0 ){.          m
2c50: 65 6d 73 65 74 28 26 70 44 62 2d 3e 63 6f 6d 70  emset(&pDb->comp
2c60: 72 65 73 73 2c 20 30 2c 20 73 69 7a 65 6f 66 28  ress, 0, sizeof(
2c70: 6c 73 6d 5f 63 6f 6d 70 72 65 73 73 29 29 3b 0a  lsm_compress));.
2c80: 20 20 20 20 20 20 20 20 20 20 70 44 62 2d 3e 63            pDb->c
2c90: 6f 6d 70 72 65 73 73 2e 69 49 64 20 3d 20 4c 53  ompress.iId = LS
2ca0: 4d 5f 43 4f 4d 50 52 45 53 53 49 4f 4e 5f 4e 4f  M_COMPRESSION_NO
2cb0: 4e 45 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73  NE;.        }els
2cc0: 65 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d  e{.          mem
2cd0: 63 70 79 28 26 70 44 62 2d 3e 63 6f 6d 70 72 65  cpy(&pDb->compre
2ce0: 73 73 2c 20 70 2c 20 73 69 7a 65 6f 66 28 6c 73  ss, p, sizeof(ls
2cf0: 6d 5f 63 6f 6d 70 72 65 73 73 29 29 3b 0a 20 20  m_compress));.  
2d00: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
2d10: 72 63 20 3d 20 6c 73 6d 46 73 43 6f 6e 66 69 67  rc = lsmFsConfig
2d20: 75 72 65 28 70 44 62 29 3b 0a 20 20 20 20 20 20  ure(pDb);.      
2d30: 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  }.      break;. 
2d40: 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 4c     }..    case L
2d50: 53 4d 5f 43 4f 4e 46 49 47 5f 53 45 54 5f 43 4f  SM_CONFIG_SET_CO
2d60: 4d 50 52 45 53 53 49 4f 4e 5f 46 41 43 54 4f 52  MPRESSION_FACTOR
2d70: 59 3a 20 7b 0a 20 20 20 20 20 20 6c 73 6d 5f 63  Y: {.      lsm_c
2d80: 6f 6d 70 72 65 73 73 5f 66 61 63 74 6f 72 79 20  ompress_factory 
2d90: 2a 70 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20  *p = va_arg(ap, 
2da0: 6c 73 6d 5f 63 6f 6d 70 72 65 73 73 5f 66 61 63  lsm_compress_fac
2db0: 74 6f 72 79 20 2a 29 3b 0a 20 20 20 20 20 20 69  tory *);.      i
2dc0: 66 28 20 70 44 62 2d 3e 66 61 63 74 6f 72 79 2e  f( pDb->factory.
2dd0: 78 46 72 65 65 20 29 7b 0a 20 20 20 20 20 20 20  xFree ){.       
2de0: 20 2f 2a 20 49 6e 76 6f 6b 65 20 61 6e 79 20 64   /* Invoke any d
2df0: 65 73 74 72 75 63 74 6f 72 20 62 65 6c 6f 6e 67  estructor belong
2e00: 69 6e 67 20 74 6f 20 74 68 65 20 63 75 72 72 65  ing to the curre
2e10: 6e 74 20 66 61 63 74 6f 72 79 2e 20 2a 2f 0a 20  nt factory. */. 
2e20: 20 20 20 20 20 20 20 70 44 62 2d 3e 66 61 63 74         pDb->fact
2e30: 6f 72 79 2e 78 46 72 65 65 28 70 44 62 2d 3e 66  ory.xFree(pDb->f
2e40: 61 63 74 6f 72 79 2e 70 43 74 78 29 3b 0a 20 20  actory.pCtx);.  
2e50: 20 20 20 20 7d 0a 20 20 20 20 20 20 6d 65 6d 63      }.      memc
2e60: 70 79 28 26 70 44 62 2d 3e 66 61 63 74 6f 72 79  py(&pDb->factory
2e70: 2c 20 70 2c 20 73 69 7a 65 6f 66 28 6c 73 6d 5f  , p, sizeof(lsm_
2e80: 63 6f 6d 70 72 65 73 73 5f 66 61 63 74 6f 72 79  compress_factory
2e90: 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  ));.      break;
2ea0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65  .    }..    case
2eb0: 20 4c 53 4d 5f 43 4f 4e 46 49 47 5f 47 45 54 5f   LSM_CONFIG_GET_
2ec0: 43 4f 4d 50 52 45 53 53 49 4f 4e 3a 20 7b 0a 20  COMPRESSION: {. 
2ed0: 20 20 20 20 20 6c 73 6d 5f 63 6f 6d 70 72 65 73       lsm_compres
2ee0: 73 20 2a 70 20 3d 20 76 61 5f 61 72 67 28 61 70  s *p = va_arg(ap
2ef0: 2c 20 6c 73 6d 5f 63 6f 6d 70 72 65 73 73 20 2a  , lsm_compress *
2f00: 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28  );.      memcpy(
2f10: 70 2c 20 26 70 44 62 2d 3e 63 6f 6d 70 72 65 73  p, &pDb->compres
2f20: 73 2c 20 73 69 7a 65 6f 66 28 6c 73 6d 5f 63 6f  s, sizeof(lsm_co
2f30: 6d 70 72 65 73 73 29 29 3b 0a 20 20 20 20 20 20  mpress));.      
2f40: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
2f50: 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20    default:.     
2f60: 20 72 63 20 3d 20 4c 53 4d 5f 4d 49 53 55 53 45   rc = LSM_MISUSE
2f70: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
2f80: 20 7d 0a 0a 20 20 76 61 5f 65 6e 64 28 61 70 29   }..  va_end(ap)
2f90: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
2fa0: 0a 0a 76 6f 69 64 20 6c 73 6d 41 70 70 65 6e 64  ..void lsmAppend
2fb0: 53 65 67 6d 65 6e 74 4c 69 73 74 28 4c 73 6d 53  SegmentList(LsmS
2fc0: 74 72 69 6e 67 20 2a 70 53 74 72 2c 20 63 68 61  tring *pStr, cha
2fd0: 72 20 2a 7a 50 72 65 2c 20 53 65 67 6d 65 6e 74  r *zPre, Segment
2fe0: 20 2a 70 53 65 67 29 7b 0a 20 20 6c 73 6d 53 74   *pSeg){.  lsmSt
2ff0: 72 69 6e 67 41 70 70 65 6e 64 66 28 70 53 74 72  ringAppendf(pStr
3000: 2c 20 22 25 73 7b 25 64 20 25 64 20 25 64 20 25  , "%s{%d %d %d %
3010: 64 7d 22 2c 20 7a 50 72 65 2c 20 0a 20 20 20 20  d}", zPre, .    
3020: 20 20 20 20 70 53 65 67 2d 3e 69 46 69 72 73 74      pSeg->iFirst
3030: 2c 20 70 53 65 67 2d 3e 69 4c 61 73 74 50 67 2c  , pSeg->iLastPg,
3040: 20 70 53 65 67 2d 3e 69 52 6f 6f 74 2c 20 70 53   pSeg->iRoot, pS
3050: 65 67 2d 3e 6e 53 69 7a 65 0a 20 20 29 3b 0a 7d  eg->nSize.  );.}
3060: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 69 6e 66  ..static int inf
3070: 6f 47 65 74 57 6f 72 6b 65 72 28 6c 73 6d 5f 64  oGetWorker(lsm_d
3080: 62 20 2a 70 44 62 2c 20 53 6e 61 70 73 68 6f 74  b *pDb, Snapshot
3090: 20 2a 2a 70 70 2c 20 69 6e 74 20 2a 70 62 55 6e   **pp, int *pbUn
30a0: 6c 6f 63 6b 29 7b 0a 20 20 69 6e 74 20 72 63 20  lock){.  int rc 
30b0: 3d 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20 20 61 73 73  = LSM_OK;..  ass
30c0: 65 72 74 28 20 2a 70 62 55 6e 6c 6f 63 6b 3d 3d  ert( *pbUnlock==
30d0: 30 20 29 3b 0a 20 20 69 66 28 20 21 70 44 62 2d  0 );.  if( !pDb-
30e0: 3e 70 57 6f 72 6b 65 72 20 29 7b 0a 20 20 20 20  >pWorker ){.    
30f0: 72 63 20 3d 20 6c 73 6d 42 65 67 69 6e 57 6f 72  rc = lsmBeginWor
3100: 6b 28 70 44 62 29 3b 0a 20 20 20 20 69 66 28 20  k(pDb);.    if( 
3110: 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65 74  rc!=LSM_OK ) ret
3120: 75 72 6e 20 72 63 3b 0a 20 20 20 20 2a 70 62 55  urn rc;.    *pbU
3130: 6e 6c 6f 63 6b 20 3d 20 31 3b 0a 20 20 7d 0a 20  nlock = 1;.  }. 
3140: 20 69 66 28 20 70 70 20 29 20 2a 70 70 20 3d 20   if( pp ) *pp = 
3150: 70 44 62 2d 3e 70 57 6f 72 6b 65 72 3b 0a 20 20  pDb->pWorker;.  
3160: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
3170: 61 74 69 63 20 76 6f 69 64 20 69 6e 66 6f 46 72  atic void infoFr
3180: 65 65 57 6f 72 6b 65 72 28 6c 73 6d 5f 64 62 20  eeWorker(lsm_db 
3190: 2a 70 44 62 2c 20 69 6e 74 20 62 55 6e 6c 6f 63  *pDb, int bUnloc
31a0: 6b 29 7b 0a 20 20 69 66 28 20 62 55 6e 6c 6f 63  k){.  if( bUnloc
31b0: 6b 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 64  k ){.    int rcd
31c0: 75 6d 6d 79 20 3d 20 4c 53 4d 5f 42 55 53 59 3b  ummy = LSM_BUSY;
31d0: 0a 20 20 20 20 6c 73 6d 46 69 6e 69 73 68 57 6f  .    lsmFinishWo
31e0: 72 6b 28 70 44 62 2c 20 30 2c 20 26 72 63 64 75  rk(pDb, 0, &rcdu
31f0: 6d 6d 79 29 3b 0a 20 20 7d 0a 7d 0a 0a 69 6e 74  mmy);.  }.}..int
3200: 20 6c 73 6d 53 74 72 75 63 74 4c 69 73 74 28 0a   lsmStructList(.
3210: 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 20    lsm_db *pDb,  
3220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3230: 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61    /* Database ha
3240: 6e 64 6c 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a  ndle */.  char *
3250: 2a 70 7a 4f 75 74 20 20 20 20 20 20 20 20 20 20  *pzOut          
3260: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
3270: 3a 20 4e 75 6c 2d 74 65 72 6d 69 6e 61 74 65 64  : Nul-terminated
3280: 20 73 74 72 69 6e 67 20 28 74 63 6c 20 6c 69 73   string (tcl lis
3290: 74 29 20 2a 2f 0a 29 7b 0a 20 20 4c 65 76 65 6c  t) */.){.  Level
32a0: 20 2a 70 54 6f 70 4c 65 76 65 6c 20 3d 20 30 3b   *pTopLevel = 0;
32b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f             /* To
32c0: 70 20 6c 65 76 65 6c 20 6f 66 20 73 6e 61 70 73  p level of snaps
32d0: 68 6f 74 20 74 6f 20 72 65 70 6f 72 74 20 6f 6e  hot to report on
32e0: 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c   */.  int rc = L
32f0: 53 4d 5f 4f 4b 3b 0a 20 20 4c 65 76 65 6c 20 2a  SM_OK;.  Level *
3300: 70 3b 0a 20 20 4c 73 6d 53 74 72 69 6e 67 20 73  p;.  LsmString s
3310: 3b 0a 20 20 53 6e 61 70 73 68 6f 74 20 2a 70 57  ;.  Snapshot *pW
3320: 6f 72 6b 65 72 3b 20 20 20 20 20 20 20 20 20 20  orker;          
3330: 20 20 20 20 2f 2a 20 57 6f 72 6b 65 72 20 73 6e      /* Worker sn
3340: 61 70 73 68 6f 74 20 2a 2f 0a 20 20 69 6e 74 20  apshot */.  int 
3350: 62 55 6e 6c 6f 63 6b 20 3d 20 30 3b 0a 0a 20 20  bUnlock = 0;..  
3360: 2f 2a 20 4f 62 74 61 69 6e 20 74 68 65 20 77 6f  /* Obtain the wo
3370: 72 6b 65 72 20 73 6e 61 70 73 68 6f 74 20 2a 2f  rker snapshot */
3380: 0a 20 20 72 63 20 3d 20 69 6e 66 6f 47 65 74 57  .  rc = infoGetW
3390: 6f 72 6b 65 72 28 70 44 62 2c 20 26 70 57 6f 72  orker(pDb, &pWor
33a0: 6b 65 72 2c 20 26 62 55 6e 6c 6f 63 6b 29 3b 0a  ker, &bUnlock);.
33b0: 20 20 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b    if( rc!=LSM_OK
33c0: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
33d0: 20 2f 2a 20 46 6f 72 6d 61 74 20 74 68 65 20 63   /* Format the c
33e0: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 73  ontents of the s
33f0: 6e 61 70 73 68 6f 74 20 61 73 20 74 65 78 74 20  napshot as text 
3400: 2a 2f 0a 20 20 70 54 6f 70 4c 65 76 65 6c 20 3d  */.  pTopLevel =
3410: 20 6c 73 6d 44 62 53 6e 61 70 73 68 6f 74 4c 65   lsmDbSnapshotLe
3420: 76 65 6c 28 70 57 6f 72 6b 65 72 29 3b 0a 20 20  vel(pWorker);.  
3430: 6c 73 6d 53 74 72 69 6e 67 49 6e 69 74 28 26 73  lsmStringInit(&s
3440: 2c 20 70 44 62 2d 3e 70 45 6e 76 29 3b 0a 20 20  , pDb->pEnv);.  
3450: 66 6f 72 28 70 3d 70 54 6f 70 4c 65 76 65 6c 3b  for(p=pTopLevel;
3460: 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70   rc==LSM_OK && p
3470: 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20  ; p=p->pNext){. 
3480: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 6c 73     int i;.    ls
3490: 6d 53 74 72 69 6e 67 41 70 70 65 6e 64 66 28 26  mStringAppendf(&
34a0: 73 2c 20 22 25 73 7b 25 64 22 2c 20 28 73 2e 6e  s, "%s{%d", (s.n
34b0: 20 3f 20 22 20 22 20 3a 20 22 22 29 2c 20 28 69   ? " " : ""), (i
34c0: 6e 74 29 70 2d 3e 69 41 67 65 29 3b 0a 20 20 20  nt)p->iAge);.   
34d0: 20 6c 73 6d 41 70 70 65 6e 64 53 65 67 6d 65 6e   lsmAppendSegmen
34e0: 74 4c 69 73 74 28 26 73 2c 20 22 20 22 2c 20 26  tList(&s, " ", &
34f0: 70 2d 3e 6c 68 73 29 3b 0a 20 20 20 20 66 6f 72  p->lhs);.    for
3500: 28 69 3d 30 3b 20 72 63 3d 3d 4c 53 4d 5f 4f 4b  (i=0; rc==LSM_OK
3510: 20 26 26 20 69 3c 70 2d 3e 6e 52 69 67 68 74 3b   && i<p->nRight;
3520: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 6c 73 6d   i++){.      lsm
3530: 41 70 70 65 6e 64 53 65 67 6d 65 6e 74 4c 69 73  AppendSegmentLis
3540: 74 28 26 73 2c 20 22 20 22 2c 20 26 70 2d 3e 61  t(&s, " ", &p->a
3550: 52 68 73 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a 20  Rhs[i]);.    }. 
3560: 20 20 20 6c 73 6d 53 74 72 69 6e 67 41 70 70 65     lsmStringAppe
3570: 6e 64 28 26 73 2c 20 22 7d 22 2c 20 31 29 3b 0a  nd(&s, "}", 1);.
3580: 20 20 7d 0a 20 20 72 63 20 3d 20 73 2e 6e 3e 3d    }.  rc = s.n>=
3590: 30 20 3f 20 4c 53 4d 5f 4f 4b 20 3a 20 4c 53 4d  0 ? LSM_OK : LSM
35a0: 5f 4e 4f 4d 45 4d 3b 0a 0a 20 20 2f 2a 20 52 65  _NOMEM;..  /* Re
35b0: 6c 65 61 73 65 20 74 68 65 20 73 6e 61 70 73 68  lease the snapsh
35c0: 6f 74 20 61 6e 64 20 72 65 74 75 72 6e 20 2a 2f  ot and return */
35d0: 0a 20 20 69 6e 66 6f 46 72 65 65 57 6f 72 6b 65  .  infoFreeWorke
35e0: 72 28 70 44 62 2c 20 62 55 6e 6c 6f 63 6b 29 3b  r(pDb, bUnlock);
35f0: 0a 20 20 2a 70 7a 4f 75 74 20 3d 20 73 2e 7a 3b  .  *pzOut = s.z;
3600: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
3610: 0a 73 74 61 74 69 63 20 69 6e 74 20 69 6e 66 6f  .static int info
3620: 46 72 65 65 6c 69 73 74 43 62 28 76 6f 69 64 20  FreelistCb(void 
3630: 2a 70 43 74 78 2c 20 69 6e 74 20 69 42 6c 6b 2c  *pCtx, int iBlk,
3640: 20 69 36 34 20 69 53 6e 61 70 73 68 6f 74 29 7b   i64 iSnapshot){
3650: 0a 20 20 4c 73 6d 53 74 72 69 6e 67 20 2a 70 53  .  LsmString *pS
3660: 74 72 20 3d 20 28 4c 73 6d 53 74 72 69 6e 67 20  tr = (LsmString 
3670: 2a 29 70 43 74 78 3b 0a 20 20 6c 73 6d 53 74 72  *)pCtx;.  lsmStr
3680: 69 6e 67 41 70 70 65 6e 64 66 28 70 53 74 72 2c  ingAppendf(pStr,
3690: 20 22 25 73 7b 25 64 20 25 6c 6c 64 7d 22 2c 20   "%s{%d %lld}", 
36a0: 28 70 53 74 72 2d 3e 6e 3f 22 20 22 3a 22 22 29  (pStr->n?" ":"")
36b0: 2c 20 69 42 6c 6b 2c 20 69 53 6e 61 70 73 68 6f  , iBlk, iSnapsho
36c0: 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a  t);.  return 0;.
36d0: 7d 0a 0a 69 6e 74 20 6c 73 6d 49 6e 66 6f 46 72  }..int lsmInfoFr
36e0: 65 65 6c 69 73 74 28 6c 73 6d 5f 64 62 20 2a 70  eelist(lsm_db *p
36f0: 44 62 2c 20 63 68 61 72 20 2a 2a 70 7a 4f 75 74  Db, char **pzOut
3700: 29 7b 0a 20 20 53 6e 61 70 73 68 6f 74 20 2a 70  ){.  Snapshot *p
3710: 57 6f 72 6b 65 72 3b 20 20 20 20 20 20 20 20 20  Worker;         
3720: 20 20 20 20 20 2f 2a 20 57 6f 72 6b 65 72 20 73       /* Worker s
3730: 6e 61 70 73 68 6f 74 20 2a 2f 0a 20 20 69 6e 74  napshot */.  int
3740: 20 62 55 6e 6c 6f 63 6b 20 3d 20 30 3b 0a 20 20   bUnlock = 0;.  
3750: 4c 73 6d 53 74 72 69 6e 67 20 73 3b 0a 20 20 69  LsmString s;.  i
3760: 6e 74 20 72 63 3b 0a 0a 20 20 2f 2a 20 4f 62 74  nt rc;..  /* Obt
3770: 61 69 6e 20 74 68 65 20 77 6f 72 6b 65 72 20 73  ain the worker s
3780: 6e 61 70 73 68 6f 74 20 2a 2f 0a 20 20 72 63 20  napshot */.  rc 
3790: 3d 20 69 6e 66 6f 47 65 74 57 6f 72 6b 65 72 28  = infoGetWorker(
37a0: 70 44 62 2c 20 26 70 57 6f 72 6b 65 72 2c 20 26  pDb, &pWorker, &
37b0: 62 55 6e 6c 6f 63 6b 29 3b 0a 20 20 69 66 28 20  bUnlock);.  if( 
37c0: 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65 74  rc!=LSM_OK ) ret
37d0: 75 72 6e 20 72 63 3b 0a 0a 20 20 6c 73 6d 53 74  urn rc;..  lsmSt
37e0: 72 69 6e 67 49 6e 69 74 28 26 73 2c 20 70 44 62  ringInit(&s, pDb
37f0: 2d 3e 70 45 6e 76 29 3b 0a 20 20 72 63 20 3d 20  ->pEnv);.  rc = 
3800: 6c 73 6d 57 61 6c 6b 46 72 65 65 6c 69 73 74 28  lsmWalkFreelist(
3810: 70 44 62 2c 20 30 2c 20 69 6e 66 6f 46 72 65 65  pDb, 0, infoFree
3820: 6c 69 73 74 43 62 2c 20 26 73 29 3b 0a 20 20 69  listCb, &s);.  i
3830: 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 7b  f( rc!=LSM_OK ){
3840: 0a 20 20 20 20 6c 73 6d 46 72 65 65 28 70 44 62  .    lsmFree(pDb
3850: 2d 3e 70 45 6e 76 2c 20 73 2e 7a 29 3b 0a 20 20  ->pEnv, s.z);.  
3860: 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 7a 4f 75  }else{.    *pzOu
3870: 74 20 3d 20 73 2e 7a 3b 0a 20 20 7d 0a 0a 20 20  t = s.z;.  }..  
3880: 2f 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20 73  /* Release the s
3890: 6e 61 70 73 68 6f 74 20 61 6e 64 20 72 65 74 75  napshot and retu
38a0: 72 6e 20 2a 2f 0a 20 20 69 6e 66 6f 46 72 65 65  rn */.  infoFree
38b0: 57 6f 72 6b 65 72 28 70 44 62 2c 20 62 55 6e 6c  Worker(pDb, bUnl
38c0: 6f 63 6b 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  ock);.  return r
38d0: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
38e0: 20 69 6e 66 6f 54 72 65 65 53 69 7a 65 28 6c 73   infoTreeSize(ls
38f0: 6d 5f 64 62 20 2a 64 62 2c 20 69 6e 74 20 2a 70  m_db *db, int *p
3900: 6e 4f 6c 64 4b 42 2c 20 69 6e 74 20 2a 70 6e 4e  nOldKB, int *pnN
3910: 65 77 4b 42 29 7b 0a 20 20 53 68 6d 48 65 61 64  ewKB){.  ShmHead
3920: 65 72 20 2a 70 53 68 6d 20 3d 20 64 62 2d 3e 70  er *pShm = db->p
3930: 53 68 6d 68 64 72 3b 0a 20 20 54 72 65 65 48 65  Shmhdr;.  TreeHe
3940: 61 64 65 72 20 2a 70 20 3d 20 26 70 53 68 6d 2d  ader *p = &pShm-
3950: 3e 68 64 72 31 3b 0a 0a 20 20 2f 2a 20 54 68 65  >hdr1;..  /* The
3960: 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f 64 65 20   following code 
3970: 73 75 66 66 65 72 73 20 66 72 6f 6d 20 74 77 6f  suffers from two
3980: 20 72 61 63 65 20 63 6f 6e 64 69 74 69 6f 6e 73   race conditions
3990: 2c 20 61 73 20 69 74 20 61 63 63 65 73 73 65 73  , as it accesses
39a0: 20 61 6e 64 0a 20 20 2a 2a 20 74 72 75 73 74 73   and.  ** trusts
39b0: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
39c0: 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 20 77   shared memory w
39d0: 69 74 68 6f 75 74 20 76 65 72 69 66 79 69 6e 67  ithout verifying
39e0: 20 63 68 65 63 6b 73 75 6d 73 3a 0a 20 20 2a 2a   checksums:.  **
39f0: 0a 20 20 2a 2a 20 20 20 2a 20 54 68 65 20 74 77  .  **   * The tw
3a00: 6f 20 76 61 6c 75 65 73 20 72 65 61 64 20 2d 20  o values read - 
3a10: 54 72 65 65 48 65 61 64 65 72 2e 72 6f 6f 74 2e  TreeHeader.root.
3a20: 6e 42 79 74 65 20 61 6e 64 20 6f 6c 64 72 6f 6f  nByte and oldroo
3a30: 74 2e 6e 42 79 74 65 20 2d 20 61 72 65 20 0a 20  t.nByte - are . 
3a40: 20 2a 2a 20 20 20 20 20 33 32 2d 62 69 74 20 66   **     32-bit f
3a50: 69 65 6c 64 73 2e 20 49 74 20 69 73 20 61 73 73  ields. It is ass
3a60: 75 6d 65 64 20 74 68 61 74 20 72 65 61 64 69 6e  umed that readin
3a70: 67 20 66 72 6f 6d 20 6f 6e 65 20 6f 66 20 74 68  g from one of th
3a80: 65 73 65 0a 20 20 2a 2a 20 20 20 20 20 69 73 20  ese.  **     is 
3a90: 61 74 6f 6d 69 63 20 2d 20 74 68 61 74 20 69 74  atomic - that it
3aa0: 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65   is not possible
3ab0: 20 74 6f 20 72 65 61 64 20 61 20 70 61 72 74 69   to read a parti
3ac0: 61 6c 6c 79 20 77 72 69 74 74 65 6e 0a 20 20 2a  ally written.  *
3ad0: 2a 20 20 20 20 20 67 61 72 62 61 67 65 20 76 61  *     garbage va
3ae0: 6c 75 65 2e 20 48 6f 77 65 76 65 72 20 74 68 65  lue. However the
3af0: 20 74 77 6f 20 76 61 6c 75 65 73 20 6d 61 79 20   two values may 
3b00: 62 65 20 6d 75 74 75 61 6c 6c 79 20 69 6e 63 6f  be mutually inco
3b10: 6e 73 69 73 74 65 6e 74 2e 20 0a 20 20 2a 2a 0a  nsistent. .  **.
3b20: 20 20 2a 2a 20 20 20 2a 20 54 72 65 65 48 65 61    **   * TreeHea
3b30: 64 65 72 2e 69 4c 6f 67 4f 66 66 20 69 73 20 61  der.iLogOff is a
3b40: 20 36 34 2d 62 69 74 20 76 61 6c 75 65 2e 20 41   64-bit value. A
3b50: 6e 64 20 6c 73 6d 43 68 65 63 6b 70 6f 69 6e 74  nd lsmCheckpoint
3b60: 4c 6f 67 4f 66 66 73 65 74 28 29 0a 20 20 2a 2a  LogOffset().  **
3b70: 20 20 20 20 20 72 65 61 64 73 20 61 20 36 34 2d       reads a 64-
3b80: 62 69 74 20 76 61 6c 75 65 20 66 72 6f 6d 20 61  bit value from a
3b90: 20 73 6e 61 70 73 68 6f 74 20 73 74 6f 72 65 64   snapshot stored
3ba0: 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d 6f 72   in shared memor
3bb0: 79 2e 20 49 74 0a 20 20 2a 2a 20 20 20 20 20 69  y. It.  **     i
3bc0: 73 20 61 73 73 75 6d 65 64 20 74 68 61 74 20 69  s assumed that i
3bd0: 6e 20 65 61 63 68 20 63 61 73 65 20 69 74 20 69  n each case it i
3be0: 73 20 70 6f 73 73 69 62 6c 65 20 74 6f 20 72 65  s possible to re
3bf0: 61 64 20 61 20 70 61 72 74 69 61 6c 6c 79 0a 20  ad a partially. 
3c00: 20 2a 2a 20 20 20 20 20 77 72 69 74 74 65 6e 20   **     written 
3c10: 67 61 72 62 61 67 65 20 76 61 6c 75 65 2e 20 49  garbage value. I
3c20: 66 20 74 68 69 73 20 6f 63 63 75 72 73 2c 20 74  f this occurs, t
3c30: 68 65 6e 20 74 68 65 20 76 61 6c 75 65 20 72 65  hen the value re
3c40: 74 75 72 6e 65 64 0a 20 20 2a 2a 20 20 20 20 20  turned.  **     
3c50: 66 6f 72 20 74 68 65 20 73 69 7a 65 20 6f 66 20  for the size of 
3c60: 74 68 65 20 22 6f 6c 64 22 20 74 72 65 65 20 6d  the "old" tree m
3c70: 61 79 20 72 65 66 6c 65 63 74 20 74 68 65 20 73  ay reflect the s
3c80: 69 7a 65 20 6f 66 20 61 6e 20 22 6f 6c 64 22 0a  ize of an "old".
3c90: 20 20 2a 2a 20 20 20 20 20 74 72 65 65 20 74 68    **     tree th
3ca0: 61 74 20 77 61 73 20 72 65 63 65 6e 74 6c 79 20  at was recently 
3cb0: 66 6c 75 73 68 65 64 20 74 6f 20 64 69 73 6b 2e  flushed to disk.
3cc0: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 47 69 76 65 6e  .  **.  ** Given
3cd0: 20 74 68 65 20 63 6f 6e 74 65 78 74 20 69 6e 20   the context in 
3ce0: 77 68 69 63 68 20 74 68 69 73 20 66 75 6e 63 74  which this funct
3cf0: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 28 61  ion is called (a
3d00: 73 20 61 20 72 65 73 75 6c 74 20 6f 66 20 61 6e  s a result of an
3d10: 0a 20 20 2a 2a 20 6c 73 6d 5f 69 6e 66 6f 28 4c  .  ** lsm_info(L
3d20: 53 4d 5f 49 4e 46 4f 5f 54 52 45 45 5f 53 49 5a  SM_INFO_TREE_SIZ
3d30: 45 29 20 72 65 71 75 65 73 74 29 2c 20 6e 65 69  E) request), nei
3d40: 74 68 65 72 20 6f 66 20 74 68 65 73 65 20 61 72  ther of these ar
3d50: 65 20 63 6f 6e 73 69 64 65 72 65 64 20 74 6f 0a  e considered to.
3d60: 20 20 2a 2a 20 62 65 20 70 72 6f 62 6c 65 6d 73    ** be problems
3d70: 2e 0a 20 20 2a 2f 0a 20 20 2a 70 6e 4e 65 77 4b  ..  */.  *pnNewK
3d80: 42 20 3d 20 28 28 69 6e 74 29 70 2d 3e 72 6f 6f  B = ((int)p->roo
3d90: 74 2e 6e 42 79 74 65 20 2b 20 31 30 32 33 29 20  t.nByte + 1023) 
3da0: 2f 20 31 30 32 34 3b 0a 20 20 69 66 28 20 70 2d  / 1024;.  if( p-
3db0: 3e 69 4f 6c 64 53 68 6d 69 64 20 29 7b 0a 20 20  >iOldShmid ){.  
3dc0: 20 20 69 66 28 20 70 2d 3e 69 4f 6c 64 4c 6f 67    if( p->iOldLog
3dd0: 3d 3d 6c 73 6d 43 68 65 63 6b 70 6f 69 6e 74 4c  ==lsmCheckpointL
3de0: 6f 67 4f 66 66 73 65 74 28 70 53 68 6d 2d 3e 61  ogOffset(pShm->a
3df0: 53 6e 61 70 31 29 20 29 7b 0a 20 20 20 20 20 20  Snap1) ){.      
3e00: 2a 70 6e 4f 6c 64 4b 42 20 3d 20 30 3b 0a 20 20  *pnOldKB = 0;.  
3e10: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a    }else{.      *
3e20: 70 6e 4f 6c 64 4b 42 20 3d 20 28 28 69 6e 74 29  pnOldKB = ((int)
3e30: 70 2d 3e 6f 6c 64 72 6f 6f 74 2e 6e 42 79 74 65  p->oldroot.nByte
3e40: 20 2b 20 31 30 32 33 29 20 2f 20 31 30 32 34 3b   + 1023) / 1024;
3e50: 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a  .    }.  }else{.
3e60: 20 20 20 20 2a 70 6e 4f 6c 64 4b 42 20 3d 20 30      *pnOldKB = 0
3e70: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
3e80: 4c 53 4d 5f 4f 4b 3b 0a 7d 0a 0a 69 6e 74 20 6c  LSM_OK;.}..int l
3e90: 73 6d 5f 69 6e 66 6f 28 6c 73 6d 5f 64 62 20 2a  sm_info(lsm_db *
3ea0: 70 44 62 2c 20 69 6e 74 20 65 50 61 72 61 6d 2c  pDb, int eParam,
3eb0: 20 2e 2e 2e 29 7b 0a 20 20 69 6e 74 20 72 63 20   ...){.  int rc 
3ec0: 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 76 61 5f 6c  = LSM_OK;.  va_l
3ed0: 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73 74 61  ist ap;.  va_sta
3ee0: 72 74 28 61 70 2c 20 65 50 61 72 61 6d 29 3b 0a  rt(ap, eParam);.
3ef0: 0a 20 20 73 77 69 74 63 68 28 20 65 50 61 72 61  .  switch( ePara
3f00: 6d 20 29 7b 0a 20 20 20 20 63 61 73 65 20 4c 53  m ){.    case LS
3f10: 4d 5f 49 4e 46 4f 5f 4e 57 52 49 54 45 3a 20 7b  M_INFO_NWRITE: {
3f20: 0a 20 20 20 20 20 20 69 6e 74 20 2a 70 69 56 61  .      int *piVa
3f30: 6c 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 69  l = va_arg(ap, i
3f40: 6e 74 20 2a 29 3b 0a 20 20 20 20 20 20 2a 70 69  nt *);.      *pi
3f50: 56 61 6c 20 3d 20 6c 73 6d 46 73 4e 57 72 69 74  Val = lsmFsNWrit
3f60: 65 28 70 44 62 2d 3e 70 46 53 29 3b 0a 20 20 20  e(pDb->pFS);.   
3f70: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
3f80: 0a 20 20 20 20 63 61 73 65 20 4c 53 4d 5f 49 4e  .    case LSM_IN
3f90: 46 4f 5f 4e 52 45 41 44 3a 20 7b 0a 20 20 20 20  FO_NREAD: {.    
3fa0: 20 20 69 6e 74 20 2a 70 69 56 61 6c 20 3d 20 76    int *piVal = v
3fb0: 61 5f 61 72 67 28 61 70 2c 20 69 6e 74 20 2a 29  a_arg(ap, int *)
3fc0: 3b 0a 20 20 20 20 20 20 2a 70 69 56 61 6c 20 3d  ;.      *piVal =
3fd0: 20 6c 73 6d 46 73 4e 52 65 61 64 28 70 44 62 2d   lsmFsNRead(pDb-
3fe0: 3e 70 46 53 29 3b 0a 20 20 20 20 20 20 62 72 65  >pFS);.      bre
3ff0: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
4000: 61 73 65 20 4c 53 4d 5f 49 4e 46 4f 5f 44 42 5f  ase LSM_INFO_DB_
4010: 53 54 52 55 43 54 55 52 45 3a 20 7b 0a 20 20 20  STRUCTURE: {.   
4020: 20 20 20 63 68 61 72 20 2a 2a 70 7a 56 61 6c 20     char **pzVal 
4030: 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61  = va_arg(ap, cha
4040: 72 20 2a 2a 29 3b 0a 20 20 20 20 20 20 72 63 20  r **);.      rc 
4050: 3d 20 6c 73 6d 53 74 72 75 63 74 4c 69 73 74 28  = lsmStructList(
4060: 70 44 62 2c 20 70 7a 56 61 6c 29 3b 0a 20 20 20  pDb, pzVal);.   
4070: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
4080: 0a 20 20 20 20 63 61 73 65 20 4c 53 4d 5f 49 4e  .    case LSM_IN
4090: 46 4f 5f 41 52 52 41 59 5f 53 54 52 55 43 54 55  FO_ARRAY_STRUCTU
40a0: 52 45 3a 20 7b 0a 20 20 20 20 20 20 4c 73 6d 50  RE: {.      LsmP
40b0: 67 6e 6f 20 70 67 6e 6f 20 3d 20 76 61 5f 61 72  gno pgno = va_ar
40c0: 67 28 61 70 2c 20 4c 73 6d 50 67 6e 6f 29 3b 0a  g(ap, LsmPgno);.
40d0: 20 20 20 20 20 20 63 68 61 72 20 2a 2a 70 7a 56        char **pzV
40e0: 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20  al = va_arg(ap, 
40f0: 63 68 61 72 20 2a 2a 29 3b 0a 20 20 20 20 20 20  char **);.      
4100: 72 63 20 3d 20 6c 73 6d 49 6e 66 6f 41 72 72 61  rc = lsmInfoArra
4110: 79 53 74 72 75 63 74 75 72 65 28 70 44 62 2c 20  yStructure(pDb, 
4120: 30 2c 20 70 67 6e 6f 2c 20 70 7a 56 61 6c 29 3b  0, pgno, pzVal);
4130: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
4140: 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 4c 53    }..    case LS
4150: 4d 5f 49 4e 46 4f 5f 41 52 52 41 59 5f 50 41 47  M_INFO_ARRAY_PAG
4160: 45 53 3a 20 7b 0a 20 20 20 20 20 20 4c 73 6d 50  ES: {.      LsmP
4170: 67 6e 6f 20 70 67 6e 6f 20 3d 20 76 61 5f 61 72  gno pgno = va_ar
4180: 67 28 61 70 2c 20 4c 73 6d 50 67 6e 6f 29 3b 0a  g(ap, LsmPgno);.
4190: 20 20 20 20 20 20 63 68 61 72 20 2a 2a 70 7a 56        char **pzV
41a0: 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20  al = va_arg(ap, 
41b0: 63 68 61 72 20 2a 2a 29 3b 0a 20 20 20 20 20 20  char **);.      
41c0: 72 63 20 3d 20 6c 73 6d 49 6e 66 6f 41 72 72 61  rc = lsmInfoArra
41d0: 79 50 61 67 65 73 28 70 44 62 2c 20 70 67 6e 6f  yPages(pDb, pgno
41e0: 2c 20 70 7a 56 61 6c 29 3b 0a 20 20 20 20 20 20  , pzVal);.      
41f0: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
4200: 20 20 63 61 73 65 20 4c 53 4d 5f 49 4e 46 4f 5f    case LSM_INFO_
4210: 50 41 47 45 5f 48 45 58 5f 44 55 4d 50 3a 0a 20  PAGE_HEX_DUMP:. 
4220: 20 20 20 63 61 73 65 20 4c 53 4d 5f 49 4e 46 4f     case LSM_INFO
4230: 5f 50 41 47 45 5f 41 53 43 49 49 5f 44 55 4d 50  _PAGE_ASCII_DUMP
4240: 3a 20 7b 0a 20 20 20 20 20 20 4c 73 6d 50 67 6e  : {.      LsmPgn
4250: 6f 20 70 67 6e 6f 20 3d 20 76 61 5f 61 72 67 28  o pgno = va_arg(
4260: 61 70 2c 20 4c 73 6d 50 67 6e 6f 29 3b 0a 20 20  ap, LsmPgno);.  
4270: 20 20 20 20 63 68 61 72 20 2a 2a 70 7a 56 61 6c      char **pzVal
4280: 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68   = va_arg(ap, ch
4290: 61 72 20 2a 2a 29 3b 0a 20 20 20 20 20 20 69 6e  ar **);.      in
42a0: 74 20 62 55 6e 6c 6f 63 6b 20 3d 20 30 3b 0a 20  t bUnlock = 0;. 
42b0: 20 20 20 20 20 72 63 20 3d 20 69 6e 66 6f 47 65       rc = infoGe
42c0: 74 57 6f 72 6b 65 72 28 70 44 62 2c 20 30 2c 20  tWorker(pDb, 0, 
42d0: 26 62 55 6e 6c 6f 63 6b 29 3b 0a 20 20 20 20 20  &bUnlock);.     
42e0: 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
42f0: 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 62  ){.        int b
4300: 48 65 78 20 3d 20 28 65 50 61 72 61 6d 3d 3d 4c  Hex = (eParam==L
4310: 53 4d 5f 49 4e 46 4f 5f 50 41 47 45 5f 48 45 58  SM_INFO_PAGE_HEX
4320: 5f 44 55 4d 50 29 3b 0a 20 20 20 20 20 20 20 20  _DUMP);.        
4330: 72 63 20 3d 20 6c 73 6d 49 6e 66 6f 50 61 67 65  rc = lsmInfoPage
4340: 44 75 6d 70 28 70 44 62 2c 20 70 67 6e 6f 2c 20  Dump(pDb, pgno, 
4350: 62 48 65 78 2c 20 70 7a 56 61 6c 29 3b 0a 20 20  bHex, pzVal);.  
4360: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 6e 66 6f      }.      info
4370: 46 72 65 65 57 6f 72 6b 65 72 28 70 44 62 2c 20  FreeWorker(pDb, 
4380: 62 55 6e 6c 6f 63 6b 29 3b 0a 20 20 20 20 20 20  bUnlock);.      
4390: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
43a0: 20 20 63 61 73 65 20 4c 53 4d 5f 49 4e 46 4f 5f    case LSM_INFO_
43b0: 4c 4f 47 5f 53 54 52 55 43 54 55 52 45 3a 20 7b  LOG_STRUCTURE: {
43c0: 0a 20 20 20 20 20 20 63 68 61 72 20 2a 2a 70 7a  .      char **pz
43d0: 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 70 2c  Val = va_arg(ap,
43e0: 20 63 68 61 72 20 2a 2a 29 3b 0a 20 20 20 20 20   char **);.     
43f0: 20 72 63 20 3d 20 6c 73 6d 49 6e 66 6f 4c 6f 67   rc = lsmInfoLog
4400: 53 74 72 75 63 74 75 72 65 28 70 44 62 2c 20 70  Structure(pDb, p
4410: 7a 56 61 6c 29 3b 0a 20 20 20 20 20 20 62 72 65  zVal);.      bre
4420: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
4430: 61 73 65 20 4c 53 4d 5f 49 4e 46 4f 5f 46 52 45  ase LSM_INFO_FRE
4440: 45 4c 49 53 54 3a 20 7b 0a 20 20 20 20 20 20 63  ELIST: {.      c
4450: 68 61 72 20 2a 2a 70 7a 56 61 6c 20 3d 20 76 61  har **pzVal = va
4460: 5f 61 72 67 28 61 70 2c 20 63 68 61 72 20 2a 2a  _arg(ap, char **
4470: 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 73  );.      rc = ls
4480: 6d 49 6e 66 6f 46 72 65 65 6c 69 73 74 28 70 44  mInfoFreelist(pD
4490: 62 2c 20 70 7a 56 61 6c 29 3b 0a 20 20 20 20 20  b, pzVal);.     
44a0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20   break;.    }.. 
44b0: 20 20 20 63 61 73 65 20 4c 53 4d 5f 49 4e 46 4f     case LSM_INFO
44c0: 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 53 49 5a 45  _CHECKPOINT_SIZE
44d0: 3a 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 2a 70  : {.      int *p
44e0: 6e 4b 42 20 3d 20 76 61 5f 61 72 67 28 61 70 2c  nKB = va_arg(ap,
44f0: 20 69 6e 74 20 2a 29 3b 0a 20 20 20 20 20 20 72   int *);.      r
4500: 63 20 3d 20 6c 73 6d 43 68 65 63 6b 70 6f 69 6e  c = lsmCheckpoin
4510: 74 53 69 7a 65 28 70 44 62 2c 20 70 6e 4b 42 29  tSize(pDb, pnKB)
4520: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
4530: 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 4c     }..    case L
4540: 53 4d 5f 49 4e 46 4f 5f 54 52 45 45 5f 53 49 5a  SM_INFO_TREE_SIZ
4550: 45 3a 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 2a  E: {.      int *
4560: 70 6e 4f 6c 64 20 3d 20 76 61 5f 61 72 67 28 61  pnOld = va_arg(a
4570: 70 2c 20 69 6e 74 20 2a 29 3b 0a 20 20 20 20 20  p, int *);.     
4580: 20 69 6e 74 20 2a 70 6e 4e 65 77 20 3d 20 76 61   int *pnNew = va
4590: 5f 61 72 67 28 61 70 2c 20 69 6e 74 20 2a 29 3b  _arg(ap, int *);
45a0: 0a 20 20 20 20 20 20 72 63 20 3d 20 69 6e 66 6f  .      rc = info
45b0: 54 72 65 65 53 69 7a 65 28 70 44 62 2c 20 70 6e  TreeSize(pDb, pn
45c0: 4f 6c 64 2c 20 70 6e 4e 65 77 29 3b 0a 20 20 20  Old, pnNew);.   
45d0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
45e0: 0a 20 20 20 20 63 61 73 65 20 4c 53 4d 5f 49 4e  .    case LSM_IN
45f0: 46 4f 5f 43 4f 4d 50 52 45 53 53 49 4f 4e 5f 49  FO_COMPRESSION_I
4600: 44 3a 20 7b 0a 20 20 20 20 20 20 75 6e 73 69 67  D: {.      unsig
4610: 6e 65 64 20 69 6e 74 20 2a 70 69 4f 75 74 20 3d  ned int *piOut =
4620: 20 76 61 5f 61 72 67 28 61 70 2c 20 75 6e 73 69   va_arg(ap, unsi
4630: 67 6e 65 64 20 69 6e 74 20 2a 29 3b 0a 20 20 20  gned int *);.   
4640: 20 20 20 69 66 28 20 70 44 62 2d 3e 70 43 6c 69     if( pDb->pCli
4650: 65 6e 74 20 29 7b 0a 20 20 20 20 20 20 20 20 2a  ent ){.        *
4660: 70 69 4f 75 74 20 3d 20 70 44 62 2d 3e 70 43 6c  piOut = pDb->pCl
4670: 69 65 6e 74 2d 3e 69 43 6d 70 49 64 3b 0a 20 20  ient->iCmpId;.  
4680: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4690: 20 20 20 72 63 20 3d 20 6c 73 6d 49 6e 66 6f 43     rc = lsmInfoC
46a0: 6f 6d 70 72 65 73 73 69 6f 6e 49 64 28 70 44 62  ompressionId(pDb
46b0: 2c 20 70 69 4f 75 74 29 3b 0a 20 20 20 20 20 20  , piOut);.      
46c0: 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  }.      break;. 
46d0: 20 20 20 7d 0a 0a 20 20 20 20 64 65 66 61 75 6c     }..    defaul
46e0: 74 3a 0a 20 20 20 20 20 20 72 63 20 3d 20 4c 53  t:.      rc = LS
46f0: 4d 5f 4d 49 53 55 53 45 3b 0a 20 20 20 20 20 20  M_MISUSE;.      
4700: 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 76 61  break;.  }..  va
4710: 5f 65 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75  _end(ap);.  retu
4720: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
4730: 20 69 6e 74 20 64 6f 57 72 69 74 65 4f 70 28 0a   int doWriteOp(.
4740: 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 0a 20    lsm_db *pDb,. 
4750: 20 69 6e 74 20 62 44 65 6c 65 74 65 52 61 6e 67   int bDeleteRang
4760: 65 2c 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  e,.  const void 
4770: 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79 2c  *pKey, int nKey,
4780: 20 20 20 20 20 2f 2a 20 4b 65 79 20 74 6f 20 77       /* Key to w
4790: 72 69 74 65 20 6f 72 20 64 65 6c 65 74 65 20 2a  rite or delete *
47a0: 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a  /.  const void *
47b0: 70 56 61 6c 2c 20 69 6e 74 20 6e 56 61 6c 20 20  pVal, int nVal  
47c0: 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20      /* Value to 
47d0: 77 72 69 74 65 2e 20 4f 72 20 6e 56 61 6c 3d 3d  write. Or nVal==
47e0: 2d 31 20 66 6f 72 20 61 20 64 65 6c 65 74 65 20  -1 for a delete 
47f0: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  */.){.  int rc =
4800: 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20   LSM_OK;        
4810: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
4820: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
4830: 62 43 6f 6d 6d 69 74 20 3d 20 30 3b 20 20 20 20  bCommit = 0;    
4840: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
4850: 72 75 65 20 74 6f 20 63 6f 6d 6d 69 74 20 62 65  rue to commit be
4860: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 20 2a  fore returning *
4870: 2f 0a 0a 20 20 69 66 28 20 70 44 62 2d 3e 6e 54  /..  if( pDb->nT
4880: 72 61 6e 73 4f 70 65 6e 3d 3d 30 20 29 7b 0a 20  ransOpen==0 ){. 
4890: 20 20 20 62 43 6f 6d 6d 69 74 20 3d 20 31 3b 0a     bCommit = 1;.
48a0: 20 20 20 20 72 63 20 3d 20 6c 73 6d 5f 62 65 67      rc = lsm_beg
48b0: 69 6e 28 70 44 62 2c 20 31 29 3b 0a 20 20 7d 0a  in(pDb, 1);.  }.
48c0: 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f  .  if( rc==LSM_O
48d0: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 65 54 79  K ){.    int eTy
48e0: 70 65 20 3d 20 28 62 44 65 6c 65 74 65 52 61 6e  pe = (bDeleteRan
48f0: 67 65 20 3f 20 4c 53 4d 5f 44 52 41 4e 47 45 20  ge ? LSM_DRANGE 
4900: 3a 20 28 6e 56 61 6c 3e 3d 30 3f 4c 53 4d 5f 57  : (nVal>=0?LSM_W
4910: 52 49 54 45 3a 4c 53 4d 5f 44 45 4c 45 54 45 29  RITE:LSM_DELETE)
4920: 29 3b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 4c  );.    rc = lsmL
4930: 6f 67 57 72 69 74 65 28 70 44 62 2c 20 65 54 79  ogWrite(pDb, eTy
4940: 70 65 2c 20 28 76 6f 69 64 20 2a 29 70 4b 65 79  pe, (void *)pKey
4950: 2c 20 6e 4b 65 79 2c 20 28 76 6f 69 64 20 2a 29  , nKey, (void *)
4960: 70 56 61 6c 2c 20 6e 56 61 6c 29 3b 0a 20 20 7d  pVal, nVal);.  }
4970: 0a 0a 20 20 6c 73 6d 53 6f 72 74 65 64 53 61 76  ..  lsmSortedSav
4980: 65 54 72 65 65 43 75 72 73 6f 72 73 28 70 44 62  eTreeCursors(pDb
4990: 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53  );..  if( rc==LS
49a0: 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20  M_OK ){.    int 
49b0: 70 67 73 7a 20 3d 20 6c 73 6d 46 73 50 61 67 65  pgsz = lsmFsPage
49c0: 53 69 7a 65 28 70 44 62 2d 3e 70 46 53 29 3b 0a  Size(pDb->pFS);.
49d0: 20 20 20 20 69 6e 74 20 6e 51 75 61 6e 74 20 3d      int nQuant =
49e0: 20 4c 53 4d 5f 41 55 54 4f 57 4f 52 4b 5f 51 55   LSM_AUTOWORK_QU
49f0: 41 4e 54 20 2a 20 70 67 73 7a 3b 0a 20 20 20 20  ANT * pgsz;.    
4a00: 69 6e 74 20 6e 42 65 66 6f 72 65 3b 0a 20 20 20  int nBefore;.   
4a10: 20 69 6e 74 20 6e 41 66 74 65 72 3b 0a 20 20 20   int nAfter;.   
4a20: 20 69 6e 74 20 6e 44 69 66 66 3b 0a 0a 20 20 20   int nDiff;..   
4a30: 20 69 66 28 20 6e 51 75 61 6e 74 3e 70 44 62 2d   if( nQuant>pDb-
4a40: 3e 6e 54 72 65 65 4c 69 6d 69 74 20 29 7b 0a 20  >nTreeLimit ){. 
4a50: 20 20 20 20 20 6e 51 75 61 6e 74 20 3d 20 4c 53       nQuant = LS
4a60: 4d 5f 4d 41 58 28 70 44 62 2d 3e 6e 54 72 65 65  M_MAX(pDb->nTree
4a70: 4c 69 6d 69 74 2c 20 70 67 73 7a 29 3b 0a 20 20  Limit, pgsz);.  
4a80: 20 20 7d 0a 0a 20 20 20 20 6e 42 65 66 6f 72 65    }..    nBefore
4a90: 20 3d 20 6c 73 6d 54 72 65 65 53 69 7a 65 28 70   = lsmTreeSize(p
4aa0: 44 62 29 3b 0a 20 20 20 20 69 66 28 20 62 44 65  Db);.    if( bDe
4ab0: 6c 65 74 65 52 61 6e 67 65 20 29 7b 0a 20 20 20  leteRange ){.   
4ac0: 20 20 20 72 63 20 3d 20 6c 73 6d 54 72 65 65 44     rc = lsmTreeD
4ad0: 65 6c 65 74 65 28 70 44 62 2c 20 28 76 6f 69 64  elete(pDb, (void
4ae0: 20 2a 29 70 4b 65 79 2c 20 6e 4b 65 79 2c 20 28   *)pKey, nKey, (
4af0: 76 6f 69 64 20 2a 29 70 56 61 6c 2c 20 6e 56 61  void *)pVal, nVa
4b00: 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  l);.    }else{. 
4b10: 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 54 72 65       rc = lsmTre
4b20: 65 49 6e 73 65 72 74 28 70 44 62 2c 20 28 76 6f  eInsert(pDb, (vo
4b30: 69 64 20 2a 29 70 4b 65 79 2c 20 6e 4b 65 79 2c  id *)pKey, nKey,
4b40: 20 28 76 6f 69 64 20 2a 29 70 56 61 6c 2c 20 6e   (void *)pVal, n
4b50: 56 61 6c 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  Val);.    }..   
4b60: 20 6e 41 66 74 65 72 20 3d 20 6c 73 6d 54 72 65   nAfter = lsmTre
4b70: 65 53 69 7a 65 28 70 44 62 29 3b 0a 20 20 20 20  eSize(pDb);.    
4b80: 6e 44 69 66 66 20 3d 20 28 6e 41 66 74 65 72 2f  nDiff = (nAfter/
4b90: 6e 51 75 61 6e 74 29 20 2d 20 28 6e 42 65 66 6f  nQuant) - (nBefo
4ba0: 72 65 2f 6e 51 75 61 6e 74 29 3b 0a 20 20 20 20  re/nQuant);.    
4bb0: 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26  if( rc==LSM_OK &
4bc0: 26 20 70 44 62 2d 3e 62 41 75 74 6f 77 6f 72 6b  & pDb->bAutowork
4bd0: 20 26 26 20 6e 44 69 66 66 21 3d 30 20 29 7b 0a   && nDiff!=0 ){.
4be0: 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 53 6f        rc = lsmSo
4bf0: 72 74 65 64 41 75 74 6f 57 6f 72 6b 28 70 44 62  rtedAutoWork(pDb
4c00: 2c 20 6e 44 69 66 66 20 2a 20 4c 53 4d 5f 41 55  , nDiff * LSM_AU
4c10: 54 4f 57 4f 52 4b 5f 51 55 41 4e 54 29 3b 0a 20  TOWORK_QUANT);. 
4c20: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49     }.  }..  /* I
4c30: 66 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  f a transaction 
4c40: 77 61 73 20 6f 70 65 6e 65 64 20 61 74 20 74 68  was opened at th
4c50: 65 20 73 74 61 72 74 20 6f 66 20 74 68 69 73 20  e start of this 
4c60: 66 75 6e 63 74 69 6f 6e 2c 20 63 6f 6d 6d 69 74  function, commit
4c70: 20 69 74 2e 20 0a 20 20 2a 2a 20 4f 72 2c 20 69   it. .  ** Or, i
4c80: 66 20 61 6e 20 65 72 72 6f 72 20 68 61 73 20 6f  f an error has o
4c90: 63 63 75 72 72 65 64 2c 20 72 6f 6c 6c 20 69 74  ccurred, roll it
4ca0: 20 62 61 63 6b 2e 20 20 2a 2f 0a 20 20 69 66 28   back.  */.  if(
4cb0: 20 62 43 6f 6d 6d 69 74 20 29 7b 0a 20 20 20 20   bCommit ){.    
4cc0: 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29  if( rc==LSM_OK )
4cd0: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d  {.      rc = lsm
4ce0: 5f 63 6f 6d 6d 69 74 28 70 44 62 2c 20 30 29 3b  _commit(pDb, 0);
4cf0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
4d00: 20 20 6c 73 6d 5f 72 6f 6c 6c 62 61 63 6b 28 70    lsm_rollback(p
4d10: 44 62 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 20 20  Db, 0);.    }.  
4d20: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
4d30: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 57 72 69 74 65 20  }../* .** Write 
4d40: 61 20 6e 65 77 20 76 61 6c 75 65 20 69 6e 74 6f  a new value into
4d50: 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a   the database..*
4d60: 2f 0a 69 6e 74 20 6c 73 6d 5f 69 6e 73 65 72 74  /.int lsm_insert
4d70: 28 0a 20 20 6c 73 6d 5f 64 62 20 2a 64 62 2c 20  (.  lsm_db *db, 
4d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4d90: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
4da0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20  connection */.  
4db0: 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b 65 79  const void *pKey
4dc0: 2c 20 69 6e 74 20 6e 4b 65 79 2c 20 20 20 20 20  , int nKey,     
4dd0: 2f 2a 20 4b 65 79 20 74 6f 20 77 72 69 74 65 20  /* Key to write 
4de0: 6f 72 20 64 65 6c 65 74 65 20 2a 2f 0a 20 20 63  or delete */.  c
4df0: 6f 6e 73 74 20 76 6f 69 64 20 2a 70 56 61 6c 2c  onst void *pVal,
4e00: 20 69 6e 74 20 6e 56 61 6c 20 20 20 20 20 20 2f   int nVal      /
4e10: 2a 20 56 61 6c 75 65 20 74 6f 20 77 72 69 74 65  * Value to write
4e20: 2e 20 4f 72 20 6e 56 61 6c 3d 3d 2d 31 20 66 6f  . Or nVal==-1 fo
4e30: 72 20 61 20 64 65 6c 65 74 65 20 2a 2f 0a 29 7b  r a delete */.){
4e40: 0a 20 20 72 65 74 75 72 6e 20 64 6f 57 72 69 74  .  return doWrit
4e50: 65 4f 70 28 64 62 2c 20 30 2c 20 70 4b 65 79 2c  eOp(db, 0, pKey,
4e60: 20 6e 4b 65 79 2c 20 70 56 61 6c 2c 20 6e 56 61   nKey, pVal, nVa
4e70: 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c  l);.}../*.** Del
4e80: 65 74 65 20 61 20 76 61 6c 75 65 20 66 72 6f 6d  ete a value from
4e90: 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 0a   the database. .
4ea0: 2a 2f 0a 69 6e 74 20 6c 73 6d 5f 64 65 6c 65 74  */.int lsm_delet
4eb0: 65 28 6c 73 6d 5f 64 62 20 2a 64 62 2c 20 63 6f  e(lsm_db *db, co
4ec0: 6e 73 74 20 76 6f 69 64 20 2a 70 4b 65 79 2c 20  nst void *pKey, 
4ed0: 69 6e 74 20 6e 4b 65 79 29 7b 0a 20 20 72 65 74  int nKey){.  ret
4ee0: 75 72 6e 20 64 6f 57 72 69 74 65 4f 70 28 64 62  urn doWriteOp(db
4ef0: 2c 20 30 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 2c  , 0, pKey, nKey,
4f00: 20 30 2c 20 2d 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a   0, -1);.}../*.*
4f10: 2a 20 44 65 6c 65 74 65 20 61 20 72 61 6e 67 65  * Delete a range
4f20: 20 6f 66 20 64 61 74 61 62 61 73 65 20 6b 65 79   of database key
4f30: 73 2e 0a 2a 2f 0a 69 6e 74 20 6c 73 6d 5f 64 65  s..*/.int lsm_de
4f40: 6c 65 74 65 5f 72 61 6e 67 65 28 0a 20 20 6c 73  lete_range(.  ls
4f50: 6d 5f 64 62 20 2a 64 62 2c 20 20 20 20 20 20 20  m_db *db,       
4f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4f70: 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65   Database handle
4f80: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64   */.  const void
4f90: 20 2a 70 4b 65 79 31 2c 20 69 6e 74 20 6e 4b 65   *pKey1, int nKe
4fa0: 79 31 2c 20 20 20 2f 2a 20 4c 6f 77 65 72 20 62  y1,   /* Lower b
4fb0: 6f 75 6e 64 20 6f 66 20 72 61 6e 67 65 20 74 6f  ound of range to
4fc0: 20 64 65 6c 65 74 65 20 2a 2f 0a 20 20 63 6f 6e   delete */.  con
4fd0: 73 74 20 76 6f 69 64 20 2a 70 4b 65 79 32 2c 20  st void *pKey2, 
4fe0: 69 6e 74 20 6e 4b 65 79 32 20 20 20 20 2f 2a 20  int nKey2    /* 
4ff0: 55 70 70 65 72 20 62 6f 75 6e 64 20 6f 66 20 72  Upper bound of r
5000: 61 6e 67 65 20 74 6f 20 64 65 6c 65 74 65 20 2a  ange to delete *
5010: 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  /.){.  int rc = 
5020: 4c 53 4d 5f 4f 4b 3b 0a 20 20 69 66 28 20 64 62  LSM_OK;.  if( db
5030: 2d 3e 78 43 6d 70 28 28 76 6f 69 64 20 2a 29 70  ->xCmp((void *)p
5040: 4b 65 79 31 2c 20 6e 4b 65 79 31 2c 20 28 76 6f  Key1, nKey1, (vo
5050: 69 64 20 2a 29 70 4b 65 79 32 2c 20 6e 4b 65 79  id *)pKey2, nKey
5060: 32 29 3c 30 20 29 7b 0a 20 20 20 20 72 63 20 3d  2)<0 ){.    rc =
5070: 20 64 6f 57 72 69 74 65 4f 70 28 64 62 2c 20 31   doWriteOp(db, 1
5080: 2c 20 70 4b 65 79 31 2c 20 6e 4b 65 79 31 2c 20  , pKey1, nKey1, 
5090: 70 4b 65 79 32 2c 20 6e 4b 65 79 32 29 3b 0a 20  pKey2, nKey2);. 
50a0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
50b0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 61 20  }../*.** Open a 
50c0: 6e 65 77 20 63 75 72 73 6f 72 20 68 61 6e 64 6c  new cursor handl
50d0: 65 2e 20 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  e. .**.** If the
50e0: 72 65 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79  re are currently
50f0: 20 6e 6f 20 6f 74 68 65 72 20 6f 70 65 6e 20 63   no other open c
5100: 75 72 73 6f 72 20 68 61 6e 64 6c 65 73 2c 20 61  ursor handles, a
5110: 6e 64 20 6e 6f 20 6f 70 65 6e 20 77 72 69 74 65  nd no open write
5120: 0a 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c  .** transaction,
5130: 20 6f 70 65 6e 20 61 20 72 65 61 64 20 74 72 61   open a read tra
5140: 6e 73 61 63 74 69 6f 6e 20 68 65 72 65 2e 0a 2a  nsaction here..*
5150: 2f 0a 69 6e 74 20 6c 73 6d 5f 63 73 72 5f 6f 70  /.int lsm_csr_op
5160: 65 6e 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20  en(lsm_db *pDb, 
5170: 6c 73 6d 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43  lsm_cursor **ppC
5180: 73 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  sr){.  int rc = 
5190: 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  LSM_OK;         
51a0: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
51b0: 20 63 6f 64 65 20 2a 2f 0a 20 20 4d 75 6c 74 69   code */.  Multi
51c0: 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 30  Cursor *pCsr = 0
51d0: 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65  ;          /* Ne
51e0: 77 20 63 75 72 73 6f 72 20 6f 62 6a 65 63 74 20  w cursor object 
51f0: 2a 2f 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 61 20  */..  /* Open a 
5200: 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  read transaction
5210: 20 69 66 20 6f 6e 65 20 69 73 20 6e 6f 74 20 61   if one is not a
5220: 6c 72 65 61 64 79 20 6f 70 65 6e 2e 20 2a 2f 0a  lready open. */.
5230: 20 20 61 73 73 65 72 74 5f 64 62 5f 73 74 61 74    assert_db_stat
5240: 65 28 70 44 62 29 3b 0a 0a 20 20 69 66 28 20 70  e(pDb);..  if( p
5250: 44 62 2d 3e 70 53 68 6d 68 64 72 3d 3d 30 20 29  Db->pShmhdr==0 )
5260: 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 44  {.    assert( pD
5270: 62 2d 3e 62 52 65 61 64 6f 6e 6c 79 20 29 3b 0a  b->bReadonly );.
5280: 20 20 20 20 72 63 20 3d 20 6c 73 6d 42 65 67 69      rc = lsmBegi
5290: 6e 52 6f 54 72 61 6e 73 28 70 44 62 29 3b 0a 20  nRoTrans(pDb);. 
52a0: 20 7d 65 6c 73 65 20 69 66 28 20 70 44 62 2d 3e   }else if( pDb->
52b0: 69 52 65 61 64 65 72 3c 30 20 29 7b 0a 20 20 20  iReader<0 ){.   
52c0: 20 72 63 20 3d 20 6c 73 6d 42 65 67 69 6e 52 65   rc = lsmBeginRe
52d0: 61 64 54 72 61 6e 73 28 70 44 62 29 3b 0a 20 20  adTrans(pDb);.  
52e0: 7d 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65  }..  /* Allocate
52f0: 20 74 68 65 20 6d 75 6c 74 69 2d 63 75 72 73 6f   the multi-curso
5300: 72 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d  r. */.  if( rc==
5310: 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  LSM_OK ){.    rc
5320: 20 3d 20 6c 73 6d 4d 43 75 72 73 6f 72 4e 65 77   = lsmMCursorNew
5330: 28 70 44 62 2c 20 26 70 43 73 72 29 3b 0a 20 20  (pDb, &pCsr);.  
5340: 7d 0a 0a 20 20 2f 2a 20 49 66 20 61 6e 20 65 72  }..  /* If an er
5350: 72 6f 72 20 68 61 73 20 6f 63 63 75 72 65 64 2c  ror has occured,
5360: 20 73 65 74 20 74 68 65 20 6f 75 74 70 75 74 20   set the output 
5370: 74 6f 20 4e 55 4c 4c 20 61 6e 64 20 64 65 6c 65  to NULL and dele
5380: 74 65 20 61 6e 79 20 70 61 72 74 69 61 6c 6c 79  te any partially
5390: 0a 20 20 2a 2a 20 61 6c 6c 6f 63 61 74 65 64 20  .  ** allocated 
53a0: 63 75 72 73 6f 72 2e 20 49 66 20 74 68 69 73 20  cursor. If this 
53b0: 6d 65 61 6e 73 20 74 68 65 72 65 20 61 72 65 20  means there are 
53c0: 6e 6f 20 6f 70 65 6e 20 63 75 72 73 6f 72 73 2c  no open cursors,
53d0: 20 72 65 6c 65 61 73 65 20 74 68 65 0a 20 20 2a   release the.  *
53e0: 2a 20 63 6c 69 65 6e 74 20 73 6e 61 70 73 68 6f  * client snapsho
53f0: 74 2e 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 21  t.  */.  if( rc!
5400: 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 6c  =LSM_OK ){.    l
5410: 73 6d 4d 43 75 72 73 6f 72 43 6c 6f 73 65 28 70  smMCursorClose(p
5420: 43 73 72 2c 20 30 29 3b 0a 20 20 20 20 64 62 52  Csr, 0);.    dbR
5430: 65 6c 65 61 73 65 43 6c 69 65 6e 74 53 6e 61 70  eleaseClientSnap
5440: 73 68 6f 74 28 70 44 62 29 3b 0a 20 20 7d 0a 0a  shot(pDb);.  }..
5450: 20 20 61 73 73 65 72 74 5f 64 62 5f 73 74 61 74    assert_db_stat
5460: 65 28 70 44 62 29 3b 0a 20 20 2a 70 70 43 73 72  e(pDb);.  *ppCsr
5470: 20 3d 20 28 6c 73 6d 5f 63 75 72 73 6f 72 20 2a   = (lsm_cursor *
5480: 29 70 43 73 72 3b 0a 20 20 72 65 74 75 72 6e 20  )pCsr;.  return 
5490: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f  rc;.}../*.** Clo
54a0: 73 65 20 61 20 63 75 72 73 6f 72 20 6f 70 65 6e  se a cursor open
54b0: 65 64 20 75 73 69 6e 67 20 6c 73 6d 5f 63 73 72  ed using lsm_csr
54c0: 5f 6f 70 65 6e 28 29 2e 0a 2a 2f 0a 69 6e 74 20  _open()..*/.int 
54d0: 6c 73 6d 5f 63 73 72 5f 63 6c 6f 73 65 28 6c 73  lsm_csr_close(ls
54e0: 6d 5f 63 75 72 73 6f 72 20 2a 70 29 7b 0a 20 20  m_cursor *p){.  
54f0: 69 66 28 20 70 20 29 7b 0a 20 20 20 20 6c 73 6d  if( p ){.    lsm
5500: 5f 64 62 20 2a 70 44 62 20 3d 20 6c 73 6d 4d 43  _db *pDb = lsmMC
5510: 75 72 73 6f 72 44 62 28 28 4d 75 6c 74 69 43 75  ursorDb((MultiCu
5520: 72 73 6f 72 20 2a 29 70 29 3b 0a 20 20 20 20 61  rsor *)p);.    a
5530: 73 73 65 72 74 5f 64 62 5f 73 74 61 74 65 28 70  ssert_db_state(p
5540: 44 62 29 3b 0a 20 20 20 20 6c 73 6d 4d 43 75 72  Db);.    lsmMCur
5550: 73 6f 72 43 6c 6f 73 65 28 28 4d 75 6c 74 69 43  sorClose((MultiC
5560: 75 72 73 6f 72 20 2a 29 70 2c 20 31 29 3b 0a 20  ursor *)p, 1);. 
5570: 20 20 20 64 62 52 65 6c 65 61 73 65 43 6c 69 65     dbReleaseClie
5580: 6e 74 53 6e 61 70 73 68 6f 74 28 70 44 62 29 3b  ntSnapshot(pDb);
5590: 0a 20 20 20 20 61 73 73 65 72 74 5f 64 62 5f 73  .    assert_db_s
55a0: 74 61 74 65 28 70 44 62 29 3b 0a 20 20 7d 0a 20  tate(pDb);.  }. 
55b0: 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a   return LSM_OK;.
55c0: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74  }../*.** Attempt
55d0: 20 74 6f 20 73 65 65 6b 20 74 68 65 20 63 75 72   to seek the cur
55e0: 73 6f 72 20 74 6f 20 74 68 65 20 64 61 74 61 62  sor to the datab
55f0: 61 73 65 20 65 6e 74 72 79 20 73 70 65 63 69 66  ase entry specif
5600: 69 65 64 20 62 79 20 70 4b 65 79 2f 6e 4b 65 79  ied by pKey/nKey
5610: 2e 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f 72  ..** If an error
5620: 20 6f 63 63 75 72 73 20 28 65 2e 67 2e 20 61 6e   occurs (e.g. an
5630: 20 4f 4f 4d 20 6f 72 20 49 4f 20 65 72 72 6f 72   OOM or IO error
5640: 29 2c 20 72 65 74 75 72 6e 20 61 6e 20 4c 53 4d  ), return an LSM
5650: 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 20   error code..** 
5660: 4f 74 68 65 72 77 69 73 65 2c 20 72 65 74 75 72  Otherwise, retur
5670: 6e 20 4c 53 4d 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74  n LSM_OK..*/.int
5680: 20 6c 73 6d 5f 63 73 72 5f 73 65 65 6b 28 6c 73   lsm_csr_seek(ls
5690: 6d 5f 63 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  m_cursor *pCsr, 
56a0: 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b 65 79  const void *pKey
56b0: 2c 20 69 6e 74 20 6e 4b 65 79 2c 20 69 6e 74 20  , int nKey, int 
56c0: 65 53 65 65 6b 29 7b 0a 20 20 72 65 74 75 72 6e  eSeek){.  return
56d0: 20 6c 73 6d 4d 43 75 72 73 6f 72 53 65 65 6b 28   lsmMCursorSeek(
56e0: 28 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 29 70  (MultiCursor *)p
56f0: 43 73 72 2c 20 30 2c 20 28 76 6f 69 64 20 2a 29  Csr, 0, (void *)
5700: 70 4b 65 79 2c 20 6e 4b 65 79 2c 20 65 53 65 65  pKey, nKey, eSee
5710: 6b 29 3b 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 5f 63  k);.}..int lsm_c
5720: 73 72 5f 6e 65 78 74 28 6c 73 6d 5f 63 75 72 73  sr_next(lsm_curs
5730: 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 72 65 74  or *pCsr){.  ret
5740: 75 72 6e 20 6c 73 6d 4d 43 75 72 73 6f 72 4e 65  urn lsmMCursorNe
5750: 78 74 28 28 4d 75 6c 74 69 43 75 72 73 6f 72 20  xt((MultiCursor 
5760: 2a 29 70 43 73 72 29 3b 0a 7d 0a 0a 69 6e 74 20  *)pCsr);.}..int 
5770: 6c 73 6d 5f 63 73 72 5f 70 72 65 76 28 6c 73 6d  lsm_csr_prev(lsm
5780: 5f 63 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a  _cursor *pCsr){.
5790: 20 20 72 65 74 75 72 6e 20 6c 73 6d 4d 43 75 72    return lsmMCur
57a0: 73 6f 72 50 72 65 76 28 28 4d 75 6c 74 69 43 75  sorPrev((MultiCu
57b0: 72 73 6f 72 20 2a 29 70 43 73 72 29 3b 0a 7d 0a  rsor *)pCsr);.}.
57c0: 0a 69 6e 74 20 6c 73 6d 5f 63 73 72 5f 66 69 72  .int lsm_csr_fir
57d0: 73 74 28 6c 73 6d 5f 63 75 72 73 6f 72 20 2a 70  st(lsm_cursor *p
57e0: 43 73 72 29 7b 0a 20 20 72 65 74 75 72 6e 20 6c  Csr){.  return l
57f0: 73 6d 4d 43 75 72 73 6f 72 46 69 72 73 74 28 28  smMCursorFirst((
5800: 4d 75 6c 74 69 43 75 72 73 6f 72 20 2a 29 70 43  MultiCursor *)pC
5810: 73 72 29 3b 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 5f  sr);.}..int lsm_
5820: 63 73 72 5f 6c 61 73 74 28 6c 73 6d 5f 63 75 72  csr_last(lsm_cur
5830: 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 72 65  sor *pCsr){.  re
5840: 74 75 72 6e 20 6c 73 6d 4d 43 75 72 73 6f 72 4c  turn lsmMCursorL
5850: 61 73 74 28 28 4d 75 6c 74 69 43 75 72 73 6f 72  ast((MultiCursor
5860: 20 2a 29 70 43 73 72 29 3b 0a 7d 0a 0a 69 6e 74   *)pCsr);.}..int
5870: 20 6c 73 6d 5f 63 73 72 5f 76 61 6c 69 64 28 6c   lsm_csr_valid(l
5880: 73 6d 5f 63 75 72 73 6f 72 20 2a 70 43 73 72 29  sm_cursor *pCsr)
5890: 7b 0a 20 20 72 65 74 75 72 6e 20 6c 73 6d 4d 43  {.  return lsmMC
58a0: 75 72 73 6f 72 56 61 6c 69 64 28 28 4d 75 6c 74  ursorValid((Mult
58b0: 69 43 75 72 73 6f 72 20 2a 29 70 43 73 72 29 3b  iCursor *)pCsr);
58c0: 0a 7d 0a 0a 69 6e 74 20 6c 73 6d 5f 63 73 72 5f  .}..int lsm_csr_
58d0: 6b 65 79 28 6c 73 6d 5f 63 75 72 73 6f 72 20 2a  key(lsm_cursor *
58e0: 70 43 73 72 2c 20 63 6f 6e 73 74 20 76 6f 69 64  pCsr, const void
58f0: 20 2a 2a 70 70 4b 65 79 2c 20 69 6e 74 20 2a 70   **ppKey, int *p
5900: 6e 4b 65 79 29 7b 0a 20 20 72 65 74 75 72 6e 20  nKey){.  return 
5910: 6c 73 6d 4d 43 75 72 73 6f 72 4b 65 79 28 28 4d  lsmMCursorKey((M
5920: 75 6c 74 69 43 75 72 73 6f 72 20 2a 29 70 43 73  ultiCursor *)pCs
5930: 72 2c 20 28 76 6f 69 64 20 2a 2a 29 70 70 4b 65  r, (void **)ppKe
5940: 79 2c 20 70 6e 4b 65 79 29 3b 0a 7d 0a 0a 69 6e  y, pnKey);.}..in
5950: 74 20 6c 73 6d 5f 63 73 72 5f 76 61 6c 75 65 28  t lsm_csr_value(
5960: 6c 73 6d 5f 63 75 72 73 6f 72 20 2a 70 43 73 72  lsm_cursor *pCsr
5970: 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 2a 70  , const void **p
5980: 70 56 61 6c 2c 20 69 6e 74 20 2a 70 6e 56 61 6c  pVal, int *pnVal
5990: 29 7b 0a 20 20 72 65 74 75 72 6e 20 6c 73 6d 4d  ){.  return lsmM
59a0: 43 75 72 73 6f 72 56 61 6c 75 65 28 28 4d 75 6c  CursorValue((Mul
59b0: 74 69 43 75 72 73 6f 72 20 2a 29 70 43 73 72 2c  tiCursor *)pCsr,
59c0: 20 28 76 6f 69 64 20 2a 2a 29 70 70 56 61 6c 2c   (void **)ppVal,
59d0: 20 70 6e 56 61 6c 29 3b 0a 7d 0a 0a 76 6f 69 64   pnVal);.}..void
59e0: 20 6c 73 6d 5f 63 6f 6e 66 69 67 5f 6c 6f 67 28   lsm_config_log(
59f0: 0a 20 20 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20  .  lsm_db *pDb, 
5a00: 0a 20 20 76 6f 69 64 20 28 2a 78 4c 6f 67 29 28  .  void (*xLog)(
5a10: 76 6f 69 64 20 2a 2c 20 69 6e 74 2c 20 63 6f 6e  void *, int, con
5a20: 73 74 20 63 68 61 72 20 2a 29 2c 20 0a 20 20 76  st char *), .  v
5a30: 6f 69 64 20 2a 70 43 74 78 0a 29 7b 0a 20 20 70  oid *pCtx.){.  p
5a40: 44 62 2d 3e 78 4c 6f 67 20 3d 20 78 4c 6f 67 3b  Db->xLog = xLog;
5a50: 0a 20 20 70 44 62 2d 3e 70 4c 6f 67 43 74 78 20  .  pDb->pLogCtx 
5a60: 3d 20 70 43 74 78 3b 0a 7d 0a 0a 76 6f 69 64 20  = pCtx;.}..void 
5a70: 6c 73 6d 5f 63 6f 6e 66 69 67 5f 77 6f 72 6b 5f  lsm_config_work_
5a80: 68 6f 6f 6b 28 0a 20 20 6c 73 6d 5f 64 62 20 2a  hook(.  lsm_db *
5a90: 70 44 62 2c 20 0a 20 20 76 6f 69 64 20 28 2a 78  pDb, .  void (*x
5aa0: 57 6f 72 6b 29 28 6c 73 6d 5f 64 62 20 2a 2c 20  Work)(lsm_db *, 
5ab0: 76 6f 69 64 20 2a 29 2c 20 0a 20 20 76 6f 69 64  void *), .  void
5ac0: 20 2a 70 43 74 78 0a 29 7b 0a 20 20 70 44 62 2d   *pCtx.){.  pDb-
5ad0: 3e 78 57 6f 72 6b 20 3d 20 78 57 6f 72 6b 3b 0a  >xWork = xWork;.
5ae0: 20 20 70 44 62 2d 3e 70 57 6f 72 6b 43 74 78 20    pDb->pWorkCtx 
5af0: 3d 20 70 43 74 78 3b 0a 7d 0a 0a 76 6f 69 64 20  = pCtx;.}..void 
5b00: 6c 73 6d 4c 6f 67 4d 65 73 73 61 67 65 28 6c 73  lsmLogMessage(ls
5b10: 6d 5f 64 62 20 2a 70 44 62 2c 20 69 6e 74 20 72  m_db *pDb, int r
5b20: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  c, const char *z
5b30: 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20  Format, ...){.  
5b40: 69 66 28 20 70 44 62 2d 3e 78 4c 6f 67 20 29 7b  if( pDb->xLog ){
5b50: 0a 20 20 20 20 4c 73 6d 53 74 72 69 6e 67 20 73  .    LsmString s
5b60: 3b 0a 20 20 20 20 76 61 5f 6c 69 73 74 20 61 70  ;.    va_list ap
5b70: 2c 20 61 70 32 3b 0a 20 20 20 20 6c 73 6d 53 74  , ap2;.    lsmSt
5b80: 72 69 6e 67 49 6e 69 74 28 26 73 2c 20 70 44 62  ringInit(&s, pDb
5b90: 2d 3e 70 45 6e 76 29 3b 0a 20 20 20 20 76 61 5f  ->pEnv);.    va_
5ba0: 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61  start(ap, zForma
5bb0: 74 29 3b 0a 20 20 20 20 76 61 5f 73 74 61 72 74  t);.    va_start
5bc0: 28 61 70 32 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a  (ap2, zFormat);.
5bd0: 20 20 20 20 6c 73 6d 53 74 72 69 6e 67 56 41 70      lsmStringVAp
5be0: 70 65 6e 64 66 28 26 73 2c 20 7a 46 6f 72 6d 61  pendf(&s, zForma
5bf0: 74 2c 20 61 70 2c 20 61 70 32 29 3b 0a 20 20 20  t, ap, ap2);.   
5c00: 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 20   va_end(ap);.   
5c10: 20 76 61 5f 65 6e 64 28 61 70 32 29 3b 0a 20 20   va_end(ap2);.  
5c20: 20 20 70 44 62 2d 3e 78 4c 6f 67 28 70 44 62 2d    pDb->xLog(pDb-
5c30: 3e 70 4c 6f 67 43 74 78 2c 20 72 63 2c 20 73 2e  >pLogCtx, rc, s.
5c40: 7a 29 3b 0a 20 20 20 20 6c 73 6d 53 74 72 69 6e  z);.    lsmStrin
5c50: 67 43 6c 65 61 72 28 26 73 29 3b 0a 20 20 7d 0a  gClear(&s);.  }.
5c60: 7d 0a 0a 69 6e 74 20 6c 73 6d 5f 62 65 67 69 6e  }..int lsm_begin
5c70: 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 69 6e  (lsm_db *pDb, in
5c80: 74 20 69 4c 65 76 65 6c 29 7b 0a 20 20 69 6e 74  t iLevel){.  int
5c90: 20 72 63 3b 0a 0a 20 20 61 73 73 65 72 74 5f 64   rc;..  assert_d
5ca0: 62 5f 73 74 61 74 65 28 20 70 44 62 20 29 3b 0a  b_state( pDb );.
5cb0: 20 20 72 63 20 3d 20 28 70 44 62 2d 3e 62 52 65    rc = (pDb->bRe
5cc0: 61 64 6f 6e 6c 79 20 3f 20 4c 53 4d 5f 52 45 41  adonly ? LSM_REA
5cd0: 44 4f 4e 4c 59 20 3a 20 4c 53 4d 5f 4f 4b 29 3b  DONLY : LSM_OK);
5ce0: 0a 0a 20 20 2f 2a 20 41 20 76 61 6c 75 65 20 6c  ..  /* A value l
5cf0: 65 73 73 20 74 68 61 6e 20 7a 65 72 6f 20 6d 65  ess than zero me
5d00: 61 6e 73 20 6f 70 65 6e 20 6f 6e 65 20 6d 6f 72  ans open one mor
5d10: 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 2a  e transaction. *
5d20: 2f 0a 20 20 69 66 28 20 69 4c 65 76 65 6c 3c 30  /.  if( iLevel<0
5d30: 20 29 20 69 4c 65 76 65 6c 20 3d 20 70 44 62 2d   ) iLevel = pDb-
5d40: 3e 6e 54 72 61 6e 73 4f 70 65 6e 20 2b 20 31 3b  >nTransOpen + 1;
5d50: 0a 20 20 69 66 28 20 69 4c 65 76 65 6c 3e 70 44  .  if( iLevel>pD
5d60: 62 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 20 29 7b  b->nTransOpen ){
5d70: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 0a 20 20 20  .    int i;..   
5d80: 20 2f 2a 20 45 78 74 65 6e 64 20 74 68 65 20 70   /* Extend the p
5d90: 44 62 2d 3e 61 54 72 61 6e 73 5b 5d 20 61 72 72  Db->aTrans[] arr
5da0: 61 79 20 69 66 20 72 65 71 75 69 72 65 64 2e 20  ay if required. 
5db0: 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c  */.    if( rc==L
5dc0: 53 4d 5f 4f 4b 20 26 26 20 70 44 62 2d 3e 6e 54  SM_OK && pDb->nT
5dd0: 72 61 6e 73 41 6c 6c 6f 63 3c 69 4c 65 76 65 6c  ransAlloc<iLevel
5de0: 20 29 7b 0a 20 20 20 20 20 20 54 72 61 6e 73 4d   ){.      TransM
5df0: 61 72 6b 20 2a 61 4e 65 77 3b 20 20 20 20 20 20  ark *aNew;      
5e00: 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 61 6c 6c        /* New all
5e10: 6f 63 61 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 20  ocation */.     
5e20: 20 69 6e 74 20 6e 42 79 74 65 20 3d 20 73 69 7a   int nByte = siz
5e30: 65 6f 66 28 54 72 61 6e 73 4d 61 72 6b 29 20 2a  eof(TransMark) *
5e40: 20 28 69 4c 65 76 65 6c 2b 31 29 3b 0a 20 20 20   (iLevel+1);.   
5e50: 20 20 20 61 4e 65 77 20 3d 20 28 54 72 61 6e 73     aNew = (Trans
5e60: 4d 61 72 6b 20 2a 29 6c 73 6d 52 65 61 6c 6c 6f  Mark *)lsmReallo
5e70: 63 28 70 44 62 2d 3e 70 45 6e 76 2c 20 70 44 62  c(pDb->pEnv, pDb
5e80: 2d 3e 61 54 72 61 6e 73 2c 20 6e 42 79 74 65 29  ->aTrans, nByte)
5e90: 3b 0a 20 20 20 20 20 20 69 66 28 20 21 61 4e 65  ;.      if( !aNe
5ea0: 77 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  w ){.        rc 
5eb0: 3d 20 4c 53 4d 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  = LSM_NOMEM;.   
5ec0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
5ed0: 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66    nByte = sizeof
5ee0: 28 54 72 61 6e 73 4d 61 72 6b 29 20 2a 20 28 69  (TransMark) * (i
5ef0: 4c 65 76 65 6c 2b 31 20 2d 20 70 44 62 2d 3e 6e  Level+1 - pDb->n
5f00: 54 72 61 6e 73 41 6c 6c 6f 63 29 3b 0a 20 20 20  TransAlloc);.   
5f10: 20 20 20 20 20 6d 65 6d 73 65 74 28 26 61 4e 65       memset(&aNe
5f20: 77 5b 70 44 62 2d 3e 6e 54 72 61 6e 73 41 6c 6c  w[pDb->nTransAll
5f30: 6f 63 5d 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a  oc], 0, nByte);.
5f40: 20 20 20 20 20 20 20 20 70 44 62 2d 3e 6e 54 72          pDb->nTr
5f50: 61 6e 73 41 6c 6c 6f 63 20 3d 20 69 4c 65 76 65  ansAlloc = iLeve
5f60: 6c 2b 31 3b 0a 20 20 20 20 20 20 20 20 70 44 62  l+1;.        pDb
5f70: 2d 3e 61 54 72 61 6e 73 20 3d 20 61 4e 65 77 3b  ->aTrans = aNew;
5f80: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
5f90: 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f      if( rc==LSM_
5fa0: 4f 4b 20 26 26 20 70 44 62 2d 3e 6e 54 72 61 6e  OK && pDb->nTran
5fb0: 73 4f 70 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20  sOpen==0 ){.    
5fc0: 20 20 72 63 20 3d 20 6c 73 6d 42 65 67 69 6e 57    rc = lsmBeginW
5fd0: 72 69 74 65 54 72 61 6e 73 28 70 44 62 29 3b 0a  riteTrans(pDb);.
5fe0: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72      }..    if( r
5ff0: 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
6000: 20 20 20 66 6f 72 28 69 3d 70 44 62 2d 3e 6e 54     for(i=pDb->nT
6010: 72 61 6e 73 4f 70 65 6e 3b 20 69 3c 69 4c 65 76  ransOpen; i<iLev
6020: 65 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  el; i++){.      
6030: 20 20 6c 73 6d 54 72 65 65 4d 61 72 6b 28 70 44    lsmTreeMark(pD
6040: 62 2c 20 26 70 44 62 2d 3e 61 54 72 61 6e 73 5b  b, &pDb->aTrans[
6050: 69 5d 2e 74 72 65 65 29 3b 0a 20 20 20 20 20 20  i].tree);.      
6060: 20 20 6c 73 6d 4c 6f 67 54 65 6c 6c 28 70 44 62    lsmLogTell(pDb
6070: 2c 20 26 70 44 62 2d 3e 61 54 72 61 6e 73 5b 69  , &pDb->aTrans[i
6080: 5d 2e 6c 6f 67 29 3b 0a 20 20 20 20 20 20 7d 0a  ].log);.      }.
6090: 20 20 20 20 20 20 70 44 62 2d 3e 6e 54 72 61 6e        pDb->nTran
60a0: 73 4f 70 65 6e 20 3d 20 69 4c 65 76 65 6c 3b 0a  sOpen = iLevel;.
60b0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
60c0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20 6c  urn rc;.}..int l
60d0: 73 6d 5f 63 6f 6d 6d 69 74 28 6c 73 6d 5f 64 62  sm_commit(lsm_db
60e0: 20 2a 70 44 62 2c 20 69 6e 74 20 69 4c 65 76 65   *pDb, int iLeve
60f0: 6c 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c  l){.  int rc = L
6100: 53 4d 5f 4f 4b 3b 0a 0a 20 20 61 73 73 65 72 74  SM_OK;..  assert
6110: 5f 64 62 5f 73 74 61 74 65 28 20 70 44 62 20 29  _db_state( pDb )
6120: 3b 0a 0a 20 20 2f 2a 20 41 20 76 61 6c 75 65 20  ;..  /* A value 
6130: 6c 65 73 73 20 74 68 61 6e 20 7a 65 72 6f 20 6d  less than zero m
6140: 65 61 6e 73 20 63 6c 6f 73 65 20 74 68 65 20 69  eans close the i
6150: 6e 6e 65 72 6d 6f 73 74 20 6e 65 73 74 65 64 20  nnermost nested 
6160: 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 2a 2f 0a  transaction. */.
6170: 20 20 69 66 28 20 69 4c 65 76 65 6c 3c 30 20 29    if( iLevel<0 )
6180: 20 69 4c 65 76 65 6c 20 3d 20 4c 53 4d 5f 4d 41   iLevel = LSM_MA
6190: 58 28 30 2c 20 70 44 62 2d 3e 6e 54 72 61 6e 73  X(0, pDb->nTrans
61a0: 4f 70 65 6e 20 2d 20 31 29 3b 0a 0a 20 20 69 66  Open - 1);..  if
61b0: 28 20 69 4c 65 76 65 6c 3c 70 44 62 2d 3e 6e 54  ( iLevel<pDb->nT
61c0: 72 61 6e 73 4f 70 65 6e 20 29 7b 0a 20 20 20 20  ransOpen ){.    
61d0: 69 66 28 20 69 4c 65 76 65 6c 3d 3d 30 20 29 7b  if( iLevel==0 ){
61e0: 0a 20 20 20 20 20 20 69 6e 74 20 72 63 32 3b 0a  .      int rc2;.
61f0: 20 20 20 20 20 20 2f 2a 20 43 6f 6d 6d 69 74 20        /* Commit 
6200: 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  the transaction 
6210: 74 6f 20 64 69 73 6b 2e 20 2a 2f 0a 20 20 20 20  to disk. */.    
6220: 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
6230: 20 29 20 72 63 20 3d 20 6c 73 6d 4c 6f 67 43 6f   ) rc = lsmLogCo
6240: 6d 6d 69 74 28 70 44 62 29 3b 0a 20 20 20 20 20  mmit(pDb);.     
6250: 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
6260: 26 26 20 70 44 62 2d 3e 65 53 61 66 65 74 79 3d  && pDb->eSafety=
6270: 3d 4c 53 4d 5f 53 41 46 45 54 59 5f 46 55 4c 4c  =LSM_SAFETY_FULL
6280: 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d   ){.        rc =
6290: 20 6c 73 6d 46 73 53 79 6e 63 4c 6f 67 28 70 44   lsmFsSyncLog(pD
62a0: 62 2d 3e 70 46 53 29 3b 0a 20 20 20 20 20 20 7d  b->pFS);.      }
62b0: 0a 20 20 20 20 20 20 72 63 32 20 3d 20 6c 73 6d  .      rc2 = lsm
62c0: 46 69 6e 69 73 68 57 72 69 74 65 54 72 61 6e 73  FinishWriteTrans
62d0: 28 70 44 62 2c 20 28 72 63 3d 3d 4c 53 4d 5f 4f  (pDb, (rc==LSM_O
62e0: 4b 29 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  K));.      if( r
62f0: 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 20 72 63 20 3d  c==LSM_OK ) rc =
6300: 20 72 63 32 3b 0a 20 20 20 20 7d 0a 20 20 20 20   rc2;.    }.    
6310: 70 44 62 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 20  pDb->nTransOpen 
6320: 3d 20 69 4c 65 76 65 6c 3b 0a 20 20 7d 0a 20 20  = iLevel;.  }.  
6330: 64 62 52 65 6c 65 61 73 65 43 6c 69 65 6e 74 53  dbReleaseClientS
6340: 6e 61 70 73 68 6f 74 28 70 44 62 29 3b 0a 20 20  napshot(pDb);.  
6350: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e  return rc;.}..in
6360: 74 20 6c 73 6d 5f 72 6f 6c 6c 62 61 63 6b 28 6c  t lsm_rollback(l
6370: 73 6d 5f 64 62 20 2a 70 44 62 2c 20 69 6e 74 20  sm_db *pDb, int 
6380: 69 4c 65 76 65 6c 29 7b 0a 20 20 69 6e 74 20 72  iLevel){.  int r
6390: 63 20 3d 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 61 73  c = LSM_OK;.  as
63a0: 73 65 72 74 5f 64 62 5f 73 74 61 74 65 28 20 70  sert_db_state( p
63b0: 44 62 20 29 3b 0a 0a 20 20 69 66 28 20 70 44 62  Db );..  if( pDb
63c0: 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 20 29 7b 0a  ->nTransOpen ){.
63d0: 20 20 20 20 2f 2a 20 41 20 76 61 6c 75 65 20 6c      /* A value l
63e0: 65 73 73 20 74 68 61 6e 20 7a 65 72 6f 20 6d 65  ess than zero me
63f0: 61 6e 73 20 63 6c 6f 73 65 20 74 68 65 20 69 6e  ans close the in
6400: 6e 65 72 6d 6f 73 74 20 6e 65 73 74 65 64 20 74  nermost nested t
6410: 72 61 6e 73 61 63 74 69 6f 6e 2e 20 2a 2f 0a 20  ransaction. */. 
6420: 20 20 20 69 66 28 20 69 4c 65 76 65 6c 3c 30 20     if( iLevel<0 
6430: 29 20 69 4c 65 76 65 6c 20 3d 20 4c 53 4d 5f 4d  ) iLevel = LSM_M
6440: 41 58 28 30 2c 20 70 44 62 2d 3e 6e 54 72 61 6e  AX(0, pDb->nTran
6450: 73 4f 70 65 6e 20 2d 20 31 29 3b 0a 0a 20 20 20  sOpen - 1);..   
6460: 20 69 66 28 20 69 4c 65 76 65 6c 3c 3d 70 44 62   if( iLevel<=pDb
6470: 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 20 29 7b 0a  ->nTransOpen ){.
6480: 20 20 20 20 20 20 54 72 61 6e 73 4d 61 72 6b 20        TransMark 
6490: 2a 70 4d 61 72 6b 20 3d 20 26 70 44 62 2d 3e 61  *pMark = &pDb->a
64a0: 54 72 61 6e 73 5b 28 69 4c 65 76 65 6c 3d 3d 30  Trans[(iLevel==0
64b0: 20 3f 20 30 20 3a 20 69 4c 65 76 65 6c 2d 31 29   ? 0 : iLevel-1)
64c0: 5d 3b 0a 20 20 20 20 20 20 6c 73 6d 54 72 65 65  ];.      lsmTree
64d0: 52 6f 6c 6c 62 61 63 6b 28 70 44 62 2c 20 26 70  Rollback(pDb, &p
64e0: 4d 61 72 6b 2d 3e 74 72 65 65 29 3b 0a 20 20 20  Mark->tree);.   
64f0: 20 20 20 69 66 28 20 69 4c 65 76 65 6c 20 29 20     if( iLevel ) 
6500: 6c 73 6d 4c 6f 67 53 65 65 6b 28 70 44 62 2c 20  lsmLogSeek(pDb, 
6510: 26 70 4d 61 72 6b 2d 3e 6c 6f 67 29 3b 0a 20 20  &pMark->log);.  
6520: 20 20 20 20 70 44 62 2d 3e 6e 54 72 61 6e 73 4f      pDb->nTransO
6530: 70 65 6e 20 3d 20 69 4c 65 76 65 6c 3b 0a 20 20  pen = iLevel;.  
6540: 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 70 44 62    }..    if( pDb
6550: 2d 3e 6e 54 72 61 6e 73 4f 70 65 6e 3d 3d 30 20  ->nTransOpen==0 
6560: 29 7b 0a 20 20 20 20 20 20 6c 73 6d 46 69 6e 69  ){.      lsmFini
6570: 73 68 57 72 69 74 65 54 72 61 6e 73 28 70 44 62  shWriteTrans(pDb
6580: 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  , 0);.    }.    
6590: 64 62 52 65 6c 65 61 73 65 43 6c 69 65 6e 74 53  dbReleaseClientS
65a0: 6e 61 70 73 68 6f 74 28 70 44 62 29 3b 0a 20 20  napshot(pDb);.  
65b0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
65c0: 7d 0a 0a 69 6e 74 20 6c 73 6d 5f 67 65 74 5f 75  }..int lsm_get_u
65d0: 73 65 72 5f 76 65 72 73 69 6f 6e 28 6c 73 6d 5f  ser_version(lsm_
65e0: 64 62 20 2a 70 44 62 2c 20 75 6e 73 69 67 6e 65  db *pDb, unsigne
65f0: 64 20 69 6e 74 20 2a 70 69 55 73 72 29 7b 0a 20  d int *piUsr){. 
6600: 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b   int rc = LSM_OK
6610: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
6620: 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
6630: 2a 2f 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 61 20  */..  /* Open a 
6640: 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  read transaction
6650: 20 69 66 20 6f 6e 65 20 69 73 20 6e 6f 74 20 61   if one is not a
6660: 6c 72 65 61 64 79 20 6f 70 65 6e 2e 20 2a 2f 0a  lready open. */.
6670: 20 20 61 73 73 65 72 74 5f 64 62 5f 73 74 61 74    assert_db_stat
6680: 65 28 70 44 62 29 3b 0a 20 20 69 66 28 20 70 44  e(pDb);.  if( pD
6690: 62 2d 3e 70 53 68 6d 68 64 72 3d 3d 30 20 29 7b  b->pShmhdr==0 ){
66a0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 44 62  .    assert( pDb
66b0: 2d 3e 62 52 65 61 64 6f 6e 6c 79 20 29 3b 0a 20  ->bReadonly );. 
66c0: 20 20 20 72 63 20 3d 20 6c 73 6d 42 65 67 69 6e     rc = lsmBegin
66d0: 52 6f 54 72 61 6e 73 28 70 44 62 29 3b 0a 20 20  RoTrans(pDb);.  
66e0: 7d 65 6c 73 65 20 69 66 28 20 70 44 62 2d 3e 69  }else if( pDb->i
66f0: 52 65 61 64 65 72 3c 30 20 29 7b 0a 20 20 20 20  Reader<0 ){.    
6700: 72 63 20 3d 20 6c 73 6d 42 65 67 69 6e 52 65 61  rc = lsmBeginRea
6710: 64 54 72 61 6e 73 28 70 44 62 29 3b 0a 20 20 7d  dTrans(pDb);.  }
6720: 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20  ..  /* Allocate 
6730: 74 68 65 20 6d 75 6c 74 69 2d 63 75 72 73 6f 72  the multi-cursor
6740: 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 4c  . */.  if( rc==L
6750: 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 69  SM_OK ){.    *pi
6760: 55 73 72 20 3d 20 70 44 62 2d 3e 74 72 65 65 68  Usr = pDb->treeh
6770: 64 72 2e 69 55 73 72 56 65 72 73 69 6f 6e 3b 0a  dr.iUsrVersion;.
6780: 20 20 7d 0a 0a 20 20 64 62 52 65 6c 65 61 73 65    }..  dbRelease
6790: 43 6c 69 65 6e 74 53 6e 61 70 73 68 6f 74 28 70  ClientSnapshot(p
67a0: 44 62 29 3b 0a 20 20 61 73 73 65 72 74 5f 64 62  Db);.  assert_db
67b0: 5f 73 74 61 74 65 28 70 44 62 29 3b 0a 20 20 72  _state(pDb);.  r
67c0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74  eturn rc;.}..int
67d0: 20 6c 73 6d 5f 73 65 74 5f 75 73 65 72 5f 76 65   lsm_set_user_ve
67e0: 72 73 69 6f 6e 28 6c 73 6d 5f 64 62 20 2a 70 44  rsion(lsm_db *pD
67f0: 62 2c 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  b, unsigned int 
6800: 69 55 73 72 29 7b 0a 20 20 69 6e 74 20 72 63 20  iUsr){.  int rc 
6810: 3d 20 4c 53 4d 5f 4f 4b 3b 20 20 20 20 20 20 20  = LSM_OK;       
6820: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
6830: 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74  rn code */.  int
6840: 20 62 43 6f 6d 6d 69 74 20 3d 20 30 3b 20 20 20   bCommit = 0;   
6850: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6860: 54 72 75 65 20 74 6f 20 63 6f 6d 6d 69 74 20 62  True to commit b
6870: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 20  efore returning 
6880: 2a 2f 0a 0a 20 20 69 66 28 20 70 44 62 2d 3e 6e  */..  if( pDb->n
6890: 54 72 61 6e 73 4f 70 65 6e 3d 3d 30 20 29 7b 0a  TransOpen==0 ){.
68a0: 20 20 20 20 62 43 6f 6d 6d 69 74 20 3d 20 31 3b      bCommit = 1;
68b0: 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 5f 62 65  .    rc = lsm_be
68c0: 67 69 6e 28 70 44 62 2c 20 31 29 3b 0a 20 20 7d  gin(pDb, 1);.  }
68d0: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f  ..  if( rc==LSM_
68e0: 4f 4b 20 29 7b 0a 20 20 20 20 70 44 62 2d 3e 74  OK ){.    pDb->t
68f0: 72 65 65 68 64 72 2e 69 55 73 72 56 65 72 73 69  reehdr.iUsrVersi
6900: 6f 6e 20 3d 20 69 55 73 72 3b 0a 20 20 7d 0a 0a  on = iUsr;.  }..
6910: 20 20 2f 2a 20 49 66 20 61 20 74 72 61 6e 73 61    /* If a transa
6920: 63 74 69 6f 6e 20 77 61 73 20 6f 70 65 6e 65 64  ction was opened
6930: 20 61 74 20 74 68 65 20 73 74 61 72 74 20 6f 66   at the start of
6940: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 2c 20   this function, 
6950: 63 6f 6d 6d 69 74 20 69 74 2e 20 0a 20 20 2a 2a  commit it. .  **
6960: 20 4f 72 2c 20 69 66 20 61 6e 20 65 72 72 6f 72   Or, if an error
6970: 20 68 61 73 20 6f 63 63 75 72 72 65 64 2c 20 72   has occurred, r
6980: 6f 6c 6c 20 69 74 20 62 61 63 6b 2e 20 20 2a 2f  oll it back.  */
6990: 0a 20 20 69 66 28 20 62 43 6f 6d 6d 69 74 20 29  .  if( bCommit )
69a0: 7b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53  {.    if( rc==LS
69b0: 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63  M_OK ){.      rc
69c0: 20 3d 20 6c 73 6d 5f 63 6f 6d 6d 69 74 28 70 44   = lsm_commit(pD
69d0: 62 2c 20 30 29 3b 0a 20 20 20 20 7d 65 6c 73 65  b, 0);.    }else
69e0: 7b 0a 20 20 20 20 20 20 6c 73 6d 5f 72 6f 6c 6c  {.      lsm_roll
69f0: 62 61 63 6b 28 70 44 62 2c 20 30 29 3b 0a 20 20  back(pDb, 0);.  
6a00: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
6a10: 6e 20 72 63 3b 0a 7d 0a                          n rc;.}.