/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact c55afd81231094ee0fd5b83dca6cff5540ba044e571b5f34bf25cedb26ff8d0e:


0000: 0a 23 69 6e 63 6c 75 64 65 20 22 6c 73 6d 74 65  .#include "lsmte
0010: 73 74 5f 74 64 62 2e 68 22 0a 23 69 6e 63 6c 75  st_tdb.h".#inclu
0020: 64 65 20 22 6c 73 6d 2e 68 22 0a 23 69 6e 63 6c  de "lsm.h".#incl
0030: 75 64 65 20 22 6c 73 6d 74 65 73 74 2e 68 22 0a  ude "lsmtest.h".
0040: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69  .#include <stdli
0050: 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73  b.h>.#include <s
0060: 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64  tring.h>.#includ
0070: 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a 23 69 6e  e <assert.h>.#in
0080: 63 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e 68 3e  clude <unistd.h>
0090: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f  .#include <stdio
00a0: 2e 68 3e 0a 0a 23 69 6e 63 6c 75 64 65 20 3c 73  .h>..#include <s
00b0: 79 73 2f 74 69 6d 65 2e 68 3e 0a 0a 74 79 70 65  ys/time.h>..type
00c0: 64 65 66 20 73 74 72 75 63 74 20 4c 73 6d 44 62  def struct LsmDb
00d0: 20 4c 73 6d 44 62 3b 0a 74 79 70 65 64 65 66 20   LsmDb;.typedef 
00e0: 73 74 72 75 63 74 20 4c 73 6d 57 6f 72 6b 65 72  struct LsmWorker
00f0: 20 4c 73 6d 57 6f 72 6b 65 72 3b 0a 74 79 70 65   LsmWorker;.type
0100: 64 65 66 20 73 74 72 75 63 74 20 4c 73 6d 46 69  def struct LsmFi
0110: 6c 65 20 4c 73 6d 46 69 6c 65 3b 0a 0a 23 64 65  le LsmFile;..#de
0120: 66 69 6e 65 20 4c 53 4d 54 45 53 54 5f 44 46 4c  fine LSMTEST_DFL
0130: 54 5f 4d 54 5f 4d 41 58 5f 43 4b 50 54 20 28 38  T_MT_MAX_CKPT (8
0140: 2a 31 30 32 34 29 0a 23 64 65 66 69 6e 65 20 4c  *1024).#define L
0150: 53 4d 54 45 53 54 5f 44 46 4c 54 5f 4d 54 5f 4d  SMTEST_DFLT_MT_M
0160: 49 4e 5f 43 4b 50 54 20 28 32 2a 31 30 32 34 29  IN_CKPT (2*1024)
0170: 0a 0a 23 69 66 64 65 66 20 4c 53 4d 5f 4d 55 54  ..#ifdef LSM_MUT
0180: 45 58 5f 50 54 48 52 45 41 44 53 0a 23 69 6e 63  EX_PTHREADS.#inc
0190: 6c 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68 3e  lude <pthread.h>
01a0: 0a 0a 23 64 65 66 69 6e 65 20 4c 53 4d 54 45 53  ..#define LSMTES
01b0: 54 5f 54 48 52 45 41 44 5f 43 4b 50 54 20 20 20  T_THREAD_CKPT   
01c0: 20 20 20 31 0a 23 64 65 66 69 6e 65 20 4c 53 4d     1.#define LSM
01d0: 54 45 53 54 5f 54 48 52 45 41 44 5f 57 4f 52 4b  TEST_THREAD_WORK
01e0: 45 52 20 20 20 20 32 0a 23 64 65 66 69 6e 65 20  ER    2.#define 
01f0: 4c 53 4d 54 45 53 54 5f 54 48 52 45 41 44 5f 57  LSMTEST_THREAD_W
0200: 4f 52 4b 45 52 5f 41 43 20 33 0a 0a 2f 2a 0a 2a  ORKER_AC 3../*.*
0210: 2a 20 54 68 65 72 65 20 61 72 65 20 73 65 76 65  * There are seve
0220: 72 61 6c 20 64 69 66 66 65 72 65 6e 74 20 74 79  ral different ty
0230: 70 65 73 20 6f 66 20 77 6f 72 6b 65 72 20 74 68  pes of worker th
0240: 72 65 61 64 73 20 74 68 61 74 20 72 75 6e 20 69  reads that run i
0250: 6e 20 64 69 66 66 65 72 65 6e 74 0a 2a 2a 20 74  n different.** t
0260: 65 73 74 20 63 6f 6e 66 69 67 75 72 61 74 69 6f  est configuratio
0270: 6e 73 2c 20 64 65 70 65 6e 64 69 6e 67 20 6f 6e  ns, depending on
0280: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 4c 73   the value of Ls
0290: 6d 57 6f 72 6b 65 72 2e 65 54 79 70 65 2e 0a 2a  mWorker.eType..*
02a0: 2a 0a 2a 2a 20 20 20 31 2e 20 43 68 65 63 6b 70  *.**   1. Checkp
02b0: 6f 69 6e 74 65 72 2e 0a 2a 2a 20 20 20 32 2e 20  ointer..**   2. 
02c0: 57 6f 72 6b 65 72 20 77 69 74 68 20 61 75 74 6f  Worker with auto
02d0: 2d 63 68 65 63 6b 70 6f 69 6e 74 2e 0a 2a 2a 20  -checkpoint..** 
02e0: 20 20 33 2e 20 57 6f 72 6b 65 72 20 77 69 74 68    3. Worker with
02f0: 6f 75 74 20 61 75 74 6f 2d 63 68 65 63 6b 70 6f  out auto-checkpo
0300: 69 6e 74 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 4c  int..*/.struct L
0310: 73 6d 57 6f 72 6b 65 72 20 7b 0a 20 20 4c 73 6d  smWorker {.  Lsm
0320: 44 62 20 2a 70 44 62 3b 20 20 20 20 20 20 20 20  Db *pDb;        
0330: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0340: 4d 61 69 6e 20 64 61 74 61 62 61 73 65 20 73 74  Main database st
0350: 72 75 63 74 75 72 65 20 2a 2f 0a 20 20 6c 73 6d  ructure */.  lsm
0360: 5f 64 62 20 2a 70 57 6f 72 6b 65 72 3b 20 20 20  _db *pWorker;   
0370: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0380: 57 6f 72 6b 65 72 20 64 61 74 61 62 61 73 65 20  Worker database 
0390: 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 70 74 68 72  handle */.  pthr
03a0: 65 61 64 5f 74 20 77 6f 72 6b 65 72 5f 74 68 72  ead_t worker_thr
03b0: 65 61 64 3b 20 20 20 20 20 20 20 20 2f 2a 20 57  ead;        /* W
03c0: 6f 72 6b 65 72 20 74 68 72 65 61 64 20 2a 2f 0a  orker thread */.
03d0: 20 20 70 74 68 72 65 61 64 5f 63 6f 6e 64 5f 74    pthread_cond_t
03e0: 20 77 6f 72 6b 65 72 5f 63 6f 6e 64 3b 20 20 20   worker_cond;   
03f0: 20 20 2f 2a 20 43 6f 6e 64 69 74 69 6f 6e 20 76    /* Condition v
0400: 61 72 20 74 68 65 20 77 6f 72 6b 65 72 20 77 61  ar the worker wa
0410: 69 74 73 20 6f 6e 20 2a 2f 0a 20 20 70 74 68 72  its on */.  pthr
0420: 65 61 64 5f 6d 75 74 65 78 5f 74 20 77 6f 72 6b  ead_mutex_t work
0430: 65 72 5f 6d 75 74 65 78 3b 20 20 20 2f 2a 20 4d  er_mutex;   /* M
0440: 75 74 65 78 20 75 73 65 64 20 77 69 74 68 20 77  utex used with w
0450: 6f 72 6b 65 72 5f 63 6f 6e 64 20 2a 2f 0a 20 20  orker_cond */.  
0460: 69 6e 74 20 62 44 6f 57 6f 72 6b 3b 20 20 20 20  int bDoWork;    
0470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0480: 2f 2a 20 53 65 74 20 74 6f 20 74 72 75 65 20 62  /* Set to true b
0490: 79 20 63 6c 69 65 6e 74 20 77 68 65 6e 20 74 68  y client when th
04a0: 65 72 65 20 69 73 20 77 6f 72 6b 20 2a 2f 0a 20  ere is work */. 
04b0: 20 69 6e 74 20 77 6f 72 6b 65 72 5f 72 63 3b 20   int worker_rc; 
04c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04d0: 20 2f 2a 20 53 74 6f 72 65 20 65 72 72 6f 72 20   /* Store error 
04e0: 63 6f 64 65 20 68 65 72 65 20 2a 2f 0a 20 20 69  code here */.  i
04f0: 6e 74 20 65 54 79 70 65 3b 20 20 20 20 20 20 20  nt eType;       
0500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0510: 2a 20 4c 53 4d 54 45 53 54 5f 54 48 52 45 41 44  * LSMTEST_THREAD
0520: 5f 58 58 58 20 63 6f 6e 73 74 61 6e 74 20 2a 2f  _XXX constant */
0530: 0a 20 20 69 6e 74 20 62 42 6c 6f 63 6b 3b 0a 7d  .  int bBlock;.}
0540: 3b 0a 23 65 6c 73 65 0a 73 74 72 75 63 74 20 4c  ;.#else.struct L
0550: 73 6d 57 6f 72 6b 65 72 20 7b 20 69 6e 74 20 77  smWorker { int w
0560: 6f 72 6b 65 72 5f 72 63 3b 20 69 6e 74 20 62 42  orker_rc; int bB
0570: 6c 6f 63 6b 3b 20 7d 3b 0a 23 65 6e 64 69 66 0a  lock; };.#endif.
0580: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 74 5f  .static void mt_
0590: 73 68 75 74 64 6f 77 6e 28 4c 73 6d 44 62 20 2a  shutdown(LsmDb *
05a0: 29 3b 0a 0a 6c 73 6d 5f 65 6e 76 20 2a 74 64 62  );..lsm_env *tdb
05b0: 5f 6c 73 6d 5f 65 6e 76 28 76 6f 69 64 29 7b 0a  _lsm_env(void){.
05c0: 20 20 73 74 61 74 69 63 20 69 6e 74 20 62 49 6e    static int bIn
05d0: 69 74 20 3d 20 30 3b 0a 20 20 73 74 61 74 69 63  it = 0;.  static
05e0: 20 6c 73 6d 5f 65 6e 76 20 65 6e 76 3b 0a 20 20   lsm_env env;.  
05f0: 69 66 28 20 62 49 6e 69 74 3d 3d 30 20 29 7b 0a  if( bInit==0 ){.
0600: 20 20 20 20 6d 65 6d 63 70 79 28 26 65 6e 76 2c      memcpy(&env,
0610: 20 6c 73 6d 5f 64 65 66 61 75 6c 74 5f 65 6e 76   lsm_default_env
0620: 28 29 2c 20 73 69 7a 65 6f 66 28 65 6e 76 29 29  (), sizeof(env))
0630: 3b 0a 20 20 20 20 62 49 6e 69 74 20 3d 20 31 3b  ;.    bInit = 1;
0640: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 26 65  .  }.  return &e
0650: 6e 76 3b 0a 7d 0a 0a 74 79 70 65 64 65 66 20 73  nv;.}..typedef s
0660: 74 72 75 63 74 20 46 69 6c 65 53 65 63 74 6f 72  truct FileSector
0670: 20 46 69 6c 65 53 65 63 74 6f 72 3b 0a 74 79 70   FileSector;.typ
0680: 65 64 65 66 20 73 74 72 75 63 74 20 46 69 6c 65  edef struct File
0690: 44 61 74 61 20 46 69 6c 65 44 61 74 61 3b 0a 0a  Data FileData;..
06a0: 73 74 72 75 63 74 20 46 69 6c 65 53 65 63 74 6f  struct FileSecto
06b0: 72 20 7b 0a 20 20 75 38 20 2a 61 4f 6c 64 3b 20  r {.  u8 *aOld; 
06c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06d0: 20 20 20 20 20 20 2f 2a 20 4f 6c 64 20 64 61 74        /* Old dat
06e0: 61 20 66 6f 72 20 74 68 69 73 20 73 65 63 74 6f  a for this secto
06f0: 72 20 2a 2f 0a 7d 3b 0a 0a 73 74 72 75 63 74 20  r */.};..struct 
0700: 46 69 6c 65 44 61 74 61 20 7b 0a 20 20 69 6e 74  FileData {.  int
0710: 20 6e 53 65 63 74 6f 72 3b 20 20 20 20 20 20 20   nSector;       
0720: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0730: 41 6c 6c 6f 63 61 74 65 64 20 73 69 7a 65 20 6f  Allocated size o
0740: 66 20 61 70 53 65 63 74 6f 72 5b 5d 20 61 72 72  f apSector[] arr
0750: 61 79 20 2a 2f 0a 20 20 46 69 6c 65 53 65 63 74  ay */.  FileSect
0760: 6f 72 20 2a 61 53 65 63 74 6f 72 3b 20 20 20 20  or *aSector;    
0770: 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79          /* Array
0780: 20 6f 66 20 66 69 6c 65 20 73 65 63 74 6f 72 73   of file sectors
0790: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 62 50   */.};../*.** bP
07a0: 72 65 70 61 72 65 43 72 61 73 68 3a 0a 2a 2a 20  repareCrash:.** 
07b0: 20 20 49 66 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74    If non-zero, t
07c0: 68 65 20 66 69 6c 65 20 77 72 61 70 70 65 72 73  he file wrappers
07d0: 20 6d 61 69 6e 74 61 69 6e 20 65 6e 6f 75 67 68   maintain enough
07e0: 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 20   in-memory data 
07f0: 74 6f 0a 2a 2a 20 20 20 73 69 6d 75 6c 61 74 65  to.**   simulate
0800: 20 74 68 65 20 65 66 66 65 63 74 20 6f 66 20 61   the effect of a
0810: 20 70 6f 77 65 72 2d 66 61 69 6c 75 72 65 20 6f   power-failure o
0820: 6e 20 74 68 65 20 66 69 6c 65 2d 73 79 73 74 65  n the file-syste
0830: 6d 20 28 69 2e 65 2e 20 74 68 61 74 0a 2a 2a 20  m (i.e. that.** 
0840: 20 20 75 6e 73 79 6e 63 65 64 20 73 65 63 74 6f    unsynced secto
0850: 72 73 20 6d 61 79 20 62 65 20 77 72 69 74 74 65  rs may be writte
0860: 6e 2c 20 6e 6f 74 20 77 72 69 74 74 65 6e 2c 20  n, not written, 
0870: 6f 72 20 6f 76 65 72 77 72 69 74 74 65 6e 20 77  or overwritten w
0880: 69 74 68 0a 2a 2a 20 20 20 61 72 62 69 74 72 61  ith.**   arbitra
0890: 72 79 20 64 61 74 61 20 77 68 65 6e 20 74 68 65  ry data when the
08a0: 20 63 72 61 73 68 20 6f 63 63 75 72 73 29 2e 0a   crash occurs)..
08b0: 2a 2a 0a 2a 2a 20 62 43 72 61 73 68 65 64 3a 0a  **.** bCrashed:.
08c0: 2a 2a 20 20 20 53 65 74 20 74 6f 20 74 72 75 65  **   Set to true
08d0: 20 61 66 74 65 72 20 61 20 63 72 61 73 68 20 69   after a crash i
08e0: 73 20 73 69 6d 75 6c 61 74 65 64 2e 20 4f 6e 63  s simulated. Onc
08f0: 65 20 74 68 69 73 20 76 61 72 69 61 62 6c 65 20  e this variable 
0900: 69 73 20 74 72 75 65 2c 20 61 6c 6c 0a 2a 2a 20  is true, all.** 
0910: 20 20 56 46 53 20 6d 65 74 68 6f 64 73 20 6f 74    VFS methods ot
0920: 68 65 72 20 74 68 61 6e 20 78 43 6c 6f 73 65 28  her than xClose(
0930: 29 20 72 65 74 75 72 6e 20 4c 53 4d 5f 49 4f 45  ) return LSM_IOE
0940: 52 52 20 61 73 20 73 6f 6f 6e 20 61 73 20 74 68  RR as soon as th
0950: 65 79 20 61 72 65 0a 2a 2a 20 20 20 63 61 6c 6c  ey are.**   call
0960: 65 64 20 28 77 69 74 68 6f 75 74 20 61 66 66 65  ed (without affe
0970: 63 74 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e  cting the conten
0980: 74 73 20 6f 66 20 74 68 65 20 66 69 6c 65 2d 73  ts of the file-s
0990: 79 73 74 65 6d 29 2e 0a 2a 2a 0a 2a 2a 20 65 6e  ystem)..**.** en
09a0: 76 3a 0a 2a 2a 20 20 20 54 68 65 20 65 6e 76 69  v:.**   The envi
09b0: 72 6f 6e 6d 65 6e 74 20 6f 62 6a 65 63 74 20 75  ronment object u
09c0: 73 65 64 20 62 79 20 61 6c 6c 20 6c 73 6d 5f 64  sed by all lsm_d
09d0: 62 2a 20 68 61 6e 64 6c 65 73 20 6f 70 65 6e 65  b* handles opene
09e0: 64 20 62 79 20 74 68 69 73 0a 2a 2a 20 20 20 6f  d by this.**   o
09f0: 62 6a 65 63 74 20 28 69 2e 65 2e 20 4c 73 6d 44  bject (i.e. LsmD
0a00: 62 2e 64 62 20 70 6c 75 73 20 61 6e 79 20 77 6f  b.db plus any wo
0a10: 72 6b 65 72 20 63 6f 6e 6e 65 63 74 69 6f 6e 73  rker connections
0a20: 29 2e 20 56 61 72 69 61 62 6c 65 20 65 6e 76 2e  ). Variable env.
0a30: 70 56 66 73 43 74 78 0a 2a 2a 20 20 20 61 6c 77  pVfsCtx.**   alw
0a40: 61 79 73 20 70 6f 69 6e 74 73 20 74 6f 20 74 68  ays points to th
0a50: 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 4c 73 6d  e containing Lsm
0a60: 44 62 20 73 74 72 75 63 74 75 72 65 2e 0a 2a 2f  Db structure..*/
0a70: 0a 73 74 72 75 63 74 20 4c 73 6d 44 62 20 7b 0a  .struct LsmDb {.
0a80: 20 20 54 65 73 74 44 62 20 62 61 73 65 3b 20 20    TestDb base;  
0a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0aa0: 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20    /* Base class 
0ab0: 2d 20 6d 65 74 68 6f 64 73 20 74 61 62 6c 65 20  - methods table 
0ac0: 2a 2f 0a 20 20 6c 73 6d 5f 65 6e 76 20 65 6e 76  */.  lsm_env env
0ad0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0ae0: 20 20 20 20 20 2f 2a 20 45 6e 76 69 72 6f 6e 6d       /* Environm
0af0: 65 6e 74 20 75 73 65 64 20 62 79 20 63 6f 6e 6e  ent used by conn
0b00: 65 63 74 69 6f 6e 20 64 62 20 2a 2f 0a 20 20 63  ection db */.  c
0b10: 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20  har *zName;     
0b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0b30: 2a 20 44 61 74 61 62 61 73 65 20 66 69 6c 65 20  * Database file 
0b40: 6e 61 6d 65 20 2a 2f 0a 20 20 6c 73 6d 5f 64 62  name */.  lsm_db
0b50: 20 2a 64 62 3b 20 20 20 20 20 20 20 20 20 20 20   *db;           
0b60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 53 4d            /* LSM
0b70: 20 64 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65   database handle
0b80: 20 2a 2f 0a 0a 20 20 6c 73 6d 5f 63 75 72 73 6f   */..  lsm_curso
0b90: 72 20 2a 70 43 73 72 3b 20 20 20 20 20 20 20 20  r *pCsr;        
0ba0: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 73 6f 72         /* Cursor
0bb0: 20 68 65 6c 64 20 6f 70 65 6e 20 64 75 72 69 6e   held open durin
0bc0: 67 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  g read transacti
0bd0: 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 42  on */.  void *pB
0be0: 75 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  uf;             
0bf0: 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65          /* Buffe
0c00: 72 20 66 6f 72 20 74 64 62 5f 66 65 74 63 68 28  r for tdb_fetch(
0c10: 29 20 6f 75 74 70 75 74 20 2a 2f 0a 20 20 69 6e  ) output */.  in
0c20: 74 20 6e 42 75 66 3b 20 20 20 20 20 20 20 20 20  t nBuf;         
0c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0c40: 20 41 6c 6c 6f 63 61 74 65 64 20 28 6e 6f 74 20   Allocated (not 
0c50: 75 73 65 64 29 20 73 69 7a 65 20 6f 66 20 70 42  used) size of pB
0c60: 75 66 20 2a 2f 0a 0a 20 20 2f 2a 20 43 72 61 73  uf */..  /* Cras
0c70: 68 20 74 65 73 74 69 6e 67 20 72 65 6c 61 74 65  h testing relate
0c80: 64 20 73 74 61 74 65 20 2a 2f 0a 20 20 69 6e 74  d state */.  int
0c90: 20 62 43 72 61 73 68 65 64 3b 20 20 20 20 20 20   bCrashed;      
0ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0cb0: 54 72 75 65 20 6f 6e 63 65 20 61 20 63 72 61 73  True once a cras
0cc0: 68 20 68 61 73 20 6f 63 63 75 72 72 65 64 20 2a  h has occurred *
0cd0: 2f 0a 20 20 69 6e 74 20 6e 41 75 74 6f 43 72 61  /.  int nAutoCra
0ce0: 73 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  sh;             
0cf0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
0d00: 20 73 79 6e 63 73 20 75 6e 74 69 6c 20 61 20 63   syncs until a c
0d10: 72 61 73 68 20 2a 2f 0a 20 20 69 6e 74 20 62 50  rash */.  int bP
0d20: 72 65 70 61 72 65 43 72 61 73 68 3b 20 20 20 20  repareCrash;    
0d30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
0d40: 65 20 74 6f 20 73 74 6f 72 65 20 77 72 69 74 65  e to store write
0d50: 73 20 69 6e 20 6d 65 6d 6f 72 79 20 2a 2f 0a 0a  s in memory */..
0d60: 20 20 2f 2a 20 55 6e 73 79 6e 63 65 64 20 64 61    /* Unsynced da
0d70: 74 61 20 28 77 68 69 6c 65 20 63 72 61 73 68 20  ta (while crash 
0d80: 74 65 73 74 69 6e 67 29 20 2a 2f 0a 20 20 69 6e  testing) */.  in
0d90: 74 20 73 7a 53 65 63 74 6f 72 3b 20 20 20 20 20  t szSector;     
0da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0db0: 20 41 73 73 75 6d 65 64 20 73 69 7a 65 20 6f 66   Assumed size of
0dc0: 20 64 69 73 6b 20 73 65 63 74 6f 72 73 20 28 35   disk sectors (5
0dd0: 31 32 42 29 20 2a 2f 0a 20 20 46 69 6c 65 44 61  12B) */.  FileDa
0de0: 74 61 20 61 46 69 6c 65 5b 32 5d 3b 20 20 20 20  ta aFile[2];    
0df0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
0e00: 61 62 61 73 65 20 61 6e 64 20 6c 6f 67 20 66 69  abase and log fi
0e10: 6c 65 20 64 61 74 61 20 2a 2f 0a 0a 20 20 2f 2a  le data */..  /*
0e20: 20 4f 74 68 65 72 20 74 65 73 74 20 69 6e 73 74   Other test inst
0e30: 72 75 6d 65 6e 74 61 74 69 6f 6e 20 2a 2f 0a 20  rumentation */. 
0e40: 20 69 6e 74 20 62 4e 6f 52 65 63 6f 76 65 72 79   int bNoRecovery
0e50: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0e60: 20 2f 2a 20 49 66 20 74 72 75 65 2c 20 61 73 73   /* If true, ass
0e70: 75 6d 65 20 44 4d 53 32 20 69 73 20 6c 6f 63 6b  ume DMS2 is lock
0e80: 65 64 20 2a 2f 0a 0a 20 20 2f 2a 20 57 6f 72 6b  ed */..  /* Work
0e90: 20 68 6f 6f 6b 20 72 65 64 69 72 65 63 74 69 6f   hook redirectio
0ea0: 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78 57  n */.  void (*xW
0eb0: 6f 72 6b 29 28 6c 73 6d 5f 64 62 20 2a 2c 20 76  ork)(lsm_db *, v
0ec0: 6f 69 64 20 2a 29 3b 0a 20 20 76 6f 69 64 20 2a  oid *);.  void *
0ed0: 70 57 6f 72 6b 43 74 78 3b 0a 0a 20 20 2f 2a 20  pWorkCtx;..  /* 
0ee0: 49 4f 20 6c 6f 67 67 69 6e 67 20 68 6f 6f 6b 20  IO logging hook 
0ef0: 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78 57 72 69  */.  void (*xWri
0f00: 74 65 48 6f 6f 6b 29 28 76 6f 69 64 20 2a 2c 20  teHook)(void *, 
0f10: 69 6e 74 2c 20 6c 73 6d 5f 69 36 34 2c 20 69 6e  int, lsm_i64, in
0f20: 74 2c 20 69 6e 74 29 3b 0a 20 20 76 6f 69 64 20  t, int);.  void 
0f30: 2a 70 57 72 69 74 65 43 74 78 3b 0a 20 20 0a 20  *pWriteCtx;.  . 
0f40: 20 2f 2a 20 57 6f 72 6b 65 72 20 74 68 72 65 61   /* Worker threa
0f50: 64 73 20 28 66 6f 72 20 6c 73 6d 5f 6d 74 29 20  ds (for lsm_mt) 
0f60: 2a 2f 0a 20 20 69 6e 74 20 6e 4d 74 4d 69 6e 43  */.  int nMtMinC
0f70: 6b 70 74 3b 0a 20 20 69 6e 74 20 6e 4d 74 4d 61  kpt;.  int nMtMa
0f80: 78 43 6b 70 74 3b 0a 20 20 69 6e 74 20 65 4d 6f  xCkpt;.  int eMo
0f90: 64 65 3b 0a 20 20 69 6e 74 20 6e 57 6f 72 6b 65  de;.  int nWorke
0fa0: 72 3b 0a 20 20 4c 73 6d 57 6f 72 6b 65 72 20 2a  r;.  LsmWorker *
0fb0: 61 57 6f 72 6b 65 72 3b 0a 7d 3b 0a 0a 23 64 65  aWorker;.};..#de
0fc0: 66 69 6e 65 20 4c 53 4d 54 45 53 54 5f 4d 4f 44  fine LSMTEST_MOD
0fd0: 45 5f 53 49 4e 47 4c 45 54 48 52 45 41 44 20 20  E_SINGLETHREAD  
0fe0: 20 20 31 0a 23 64 65 66 69 6e 65 20 4c 53 4d 54    1.#define LSMT
0ff0: 45 53 54 5f 4d 4f 44 45 5f 42 41 43 4b 47 52 4f  EST_MODE_BACKGRO
1000: 55 4e 44 5f 43 4b 50 54 20 32 0a 23 64 65 66 69  UND_CKPT 2.#defi
1010: 6e 65 20 4c 53 4d 54 45 53 54 5f 4d 4f 44 45 5f  ne LSMTEST_MODE_
1020: 42 41 43 4b 47 52 4f 55 4e 44 5f 57 4f 52 4b 20  BACKGROUND_WORK 
1030: 33 0a 23 64 65 66 69 6e 65 20 4c 53 4d 54 45 53  3.#define LSMTES
1040: 54 5f 4d 4f 44 45 5f 42 41 43 4b 47 52 4f 55 4e  T_MODE_BACKGROUN
1050: 44 5f 42 4f 54 48 20 34 0a 0a 2f 2a 2a 2a 2a 2a  D_BOTH 4../*****
1060: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1070: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1080: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1090: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
10a0: 2a 2a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****.***********
10b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
10c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
10d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
10e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a  ***************.
10f0: 2a 2a 20 42 65 67 69 6e 20 74 65 73 74 20 56 46  ** Begin test VF
1100: 53 20 63 6f 64 65 2e 0a 2a 2f 0a 0a 73 74 72 75  S code..*/..stru
1110: 63 74 20 4c 73 6d 46 69 6c 65 20 7b 0a 20 20 6c  ct LsmFile {.  l
1120: 73 6d 5f 66 69 6c 65 20 2a 70 52 65 61 6c 3b 20  sm_file *pReal; 
1130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1140: 2a 20 52 65 61 6c 20 75 6e 64 65 72 6c 79 69 6e  * Real underlyin
1150: 67 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20  g file */.  int 
1160: 62 4c 6f 67 3b 20 20 20 20 20 20 20 20 20 20 20  bLog;           
1170: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
1180: 72 75 65 20 66 6f 72 20 6c 6f 67 20 66 69 6c 65  rue for log file
1190: 2e 20 46 61 6c 73 65 20 66 6f 72 20 64 62 20 66  . False for db f
11a0: 69 6c 65 20 2a 2f 0a 20 20 4c 73 6d 44 62 20 2a  ile */.  LsmDb *
11b0: 70 44 62 3b 20 20 20 20 20 20 20 20 20 20 20 20  pDb;            
11c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
11d0: 62 61 73 65 20 68 61 6e 64 6c 65 20 74 68 61 74  base handle that
11e0: 20 75 73 65 73 20 74 68 69 73 20 66 69 6c 65 20   uses this file 
11f0: 2a 2f 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 69 6e  */.};..static in
1200: 74 20 74 65 73 74 45 6e 76 46 75 6c 6c 70 61 74  t testEnvFullpat
1210: 68 28 0a 20 20 6c 73 6d 5f 65 6e 76 20 2a 70 45  h(.  lsm_env *pE
1220: 6e 76 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  nv,             
1230: 20 20 20 20 20 2f 2a 20 45 6e 76 69 72 6f 6e 6d       /* Environm
1240: 65 6e 74 20 66 6f 72 20 63 75 72 72 65 6e 74 20  ent for current 
1250: 4c 73 6d 44 62 20 2a 2f 0a 20 20 63 6f 6e 73 74  LsmDb */.  const
1260: 20 63 68 61 72 20 2a 7a 46 69 6c 65 2c 20 20 20   char *zFile,   
1270: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
1280: 6c 61 74 69 76 65 20 70 61 74 68 20 6e 61 6d 65  lative path name
1290: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 4f 75 74   */.  char *zOut
12a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
12b0: 20 20 20 20 20 20 2f 2a 20 4f 75 74 70 75 74 20        /* Output 
12c0: 62 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20  buffer */.  int 
12d0: 2a 70 6e 4f 75 74 20 20 20 20 20 20 20 20 20 20  *pnOut          
12e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
12f0: 4e 2f 4f 55 54 3a 20 53 69 7a 65 20 6f 66 20 6f  N/OUT: Size of o
1300: 75 74 70 75 74 20 62 75 66 66 65 72 20 2a 2f 0a  utput buffer */.
1310: 29 7b 0a 20 20 6c 73 6d 5f 65 6e 76 20 2a 70 52  ){.  lsm_env *pR
1320: 65 61 6c 45 6e 76 20 3d 20 74 64 62 5f 6c 73 6d  ealEnv = tdb_lsm
1330: 5f 65 6e 76 28 29 3b 0a 20 20 72 65 74 75 72 6e  _env();.  return
1340: 20 70 52 65 61 6c 45 6e 76 2d 3e 78 46 75 6c 6c   pRealEnv->xFull
1350: 70 61 74 68 28 70 52 65 61 6c 45 6e 76 2c 20 7a  path(pRealEnv, z
1360: 46 69 6c 65 2c 20 7a 4f 75 74 2c 20 70 6e 4f 75  File, zOut, pnOu
1370: 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  t);.}..static in
1380: 74 20 74 65 73 74 45 6e 76 4f 70 65 6e 28 0a 20  t testEnvOpen(. 
1390: 20 6c 73 6d 5f 65 6e 76 20 2a 70 45 6e 76 2c 20   lsm_env *pEnv, 
13a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13b0: 20 2f 2a 20 45 6e 76 69 72 6f 6e 6d 65 6e 74 20   /* Environment 
13c0: 66 6f 72 20 63 75 72 72 65 6e 74 20 4c 73 6d 44  for current LsmD
13d0: 62 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  b */.  const cha
13e0: 72 20 2a 7a 46 69 6c 65 2c 20 20 20 20 20 20 20  r *zFile,       
13f0: 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f         /* Name o
1400: 66 20 66 69 6c 65 20 74 6f 20 6f 70 65 6e 20 2a  f file to open *
1410: 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73 2c 0a 20  /.  int flags,. 
1420: 20 6c 73 6d 5f 66 69 6c 65 20 2a 2a 70 70 46 69   lsm_file **ppFi
1430: 6c 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20  le              
1440: 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 66 69 6c   /* OUT: New fil
1450: 65 20 68 61 6e 64 6c 65 20 6f 62 6a 65 63 74 20  e handle object 
1460: 2a 2f 0a 29 7b 0a 20 20 6c 73 6d 5f 65 6e 76 20  */.){.  lsm_env 
1470: 2a 70 52 65 61 6c 45 6e 76 20 3d 20 74 64 62 5f  *pRealEnv = tdb_
1480: 6c 73 6d 5f 65 6e 76 28 29 3b 0a 20 20 4c 73 6d  lsm_env();.  Lsm
1490: 44 62 20 2a 70 44 62 20 3d 20 28 4c 73 6d 44 62  Db *pDb = (LsmDb
14a0: 20 2a 29 70 45 6e 76 2d 3e 70 56 66 73 43 74 78   *)pEnv->pVfsCtx
14b0: 3b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  ;.  int rc;     
14c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14d0: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f      /* Return Co
14e0: 64 65 20 2a 2f 0a 20 20 4c 73 6d 46 69 6c 65 20  de */.  LsmFile 
14f0: 2a 70 52 65 74 3b 20 20 20 20 20 20 20 20 20 20  *pRet;          
1500: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6e          /* The n
1510: 65 77 20 66 69 6c 65 20 68 61 6e 64 6c 65 20 2a  ew file handle *
1520: 2f 0a 20 20 69 6e 74 20 6e 46 69 6c 65 3b 20 20  /.  int nFile;  
1530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1540: 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66      /* Length of
1550: 20 73 74 72 69 6e 67 20 7a 46 69 6c 65 20 69 6e   string zFile in
1560: 20 62 79 74 65 73 20 2a 2f 0a 0a 20 20 6e 46 69   bytes */..  nFi
1570: 6c 65 20 3d 20 73 74 72 6c 65 6e 28 7a 46 69 6c  le = strlen(zFil
1580: 65 29 3b 0a 20 20 70 52 65 74 20 3d 20 28 4c 73  e);.  pRet = (Ls
1590: 6d 46 69 6c 65 20 2a 29 74 65 73 74 4d 61 6c 6c  mFile *)testMall
15a0: 6f 63 28 73 69 7a 65 6f 66 28 4c 73 6d 46 69 6c  oc(sizeof(LsmFil
15b0: 65 29 29 3b 0a 20 20 70 52 65 74 2d 3e 70 44 62  e));.  pRet->pDb
15c0: 20 3d 20 70 44 62 3b 0a 20 20 70 52 65 74 2d 3e   = pDb;.  pRet->
15d0: 62 4c 6f 67 20 3d 20 28 6e 46 69 6c 65 20 3e 20  bLog = (nFile > 
15e0: 34 20 26 26 20 30 3d 3d 6d 65 6d 63 6d 70 28 22  4 && 0==memcmp("
15f0: 2d 6c 6f 67 22 2c 20 26 7a 46 69 6c 65 5b 6e 46  -log", &zFile[nF
1600: 69 6c 65 2d 34 5d 2c 20 34 29 29 3b 0a 0a 20 20  ile-4], 4));..  
1610: 72 63 20 3d 20 70 52 65 61 6c 45 6e 76 2d 3e 78  rc = pRealEnv->x
1620: 4f 70 65 6e 28 70 52 65 61 6c 45 6e 76 2c 20 7a  Open(pRealEnv, z
1630: 46 69 6c 65 2c 20 66 6c 61 67 73 2c 20 26 70 52  File, flags, &pR
1640: 65 74 2d 3e 70 52 65 61 6c 29 3b 0a 20 20 69 66  et->pReal);.  if
1650: 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a  ( rc!=LSM_OK ){.
1660: 20 20 20 20 74 65 73 74 46 72 65 65 28 70 52 65      testFree(pRe
1670: 74 29 3b 0a 20 20 20 20 70 52 65 74 20 3d 20 30  t);.    pRet = 0
1680: 3b 0a 20 20 7d 0a 0a 20 20 2a 70 70 46 69 6c 65  ;.  }..  *ppFile
1690: 20 3d 20 28 6c 73 6d 5f 66 69 6c 65 20 2a 29 70   = (lsm_file *)p
16a0: 52 65 74 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  Ret;.  return rc
16b0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
16c0: 74 65 73 74 45 6e 76 52 65 61 64 28 6c 73 6d 5f  testEnvRead(lsm_
16d0: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 6c 73 6d  file *pFile, lsm
16e0: 5f 69 36 34 20 69 4f 66 66 2c 20 76 6f 69 64 20  _i64 iOff, void 
16f0: 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74  *pData, int nDat
1700: 61 29 7b 0a 20 20 6c 73 6d 5f 65 6e 76 20 2a 70  a){.  lsm_env *p
1710: 52 65 61 6c 45 6e 76 20 3d 20 74 64 62 5f 6c 73  RealEnv = tdb_ls
1720: 6d 5f 65 6e 76 28 29 3b 0a 20 20 4c 73 6d 46 69  m_env();.  LsmFi
1730: 6c 65 20 2a 70 20 3d 20 28 4c 73 6d 46 69 6c 65  le *p = (LsmFile
1740: 20 2a 29 70 46 69 6c 65 3b 0a 20 20 69 66 28 20   *)pFile;.  if( 
1750: 70 2d 3e 70 44 62 2d 3e 62 43 72 61 73 68 65 64  p->pDb->bCrashed
1760: 20 29 20 72 65 74 75 72 6e 20 4c 53 4d 5f 49 4f   ) return LSM_IO
1770: 45 52 52 3b 0a 20 20 72 65 74 75 72 6e 20 70 52  ERR;.  return pR
1780: 65 61 6c 45 6e 76 2d 3e 78 52 65 61 64 28 70 2d  ealEnv->xRead(p-
1790: 3e 70 52 65 61 6c 2c 20 69 4f 66 66 2c 20 70 44  >pReal, iOff, pD
17a0: 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 7d 0a 0a  ata, nData);.}..
17b0: 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74 45  static int testE
17c0: 6e 76 57 72 69 74 65 28 6c 73 6d 5f 66 69 6c 65  nvWrite(lsm_file
17d0: 20 2a 70 46 69 6c 65 2c 20 6c 73 6d 5f 69 36 34   *pFile, lsm_i64
17e0: 20 69 4f 66 66 2c 20 76 6f 69 64 20 2a 70 44 61   iOff, void *pDa
17f0: 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a  ta, int nData){.
1800: 20 20 6c 73 6d 5f 65 6e 76 20 2a 70 52 65 61 6c    lsm_env *pReal
1810: 45 6e 76 20 3d 20 74 64 62 5f 6c 73 6d 5f 65 6e  Env = tdb_lsm_en
1820: 76 28 29 3b 0a 20 20 4c 73 6d 46 69 6c 65 20 2a  v();.  LsmFile *
1830: 70 20 3d 20 28 4c 73 6d 46 69 6c 65 20 2a 29 70  p = (LsmFile *)p
1840: 46 69 6c 65 3b 0a 20 20 4c 73 6d 44 62 20 2a 70  File;.  LsmDb *p
1850: 44 62 20 3d 20 70 2d 3e 70 44 62 3b 0a 0a 20 20  Db = p->pDb;..  
1860: 69 66 28 20 70 44 62 2d 3e 62 43 72 61 73 68 65  if( pDb->bCrashe
1870: 64 20 29 20 72 65 74 75 72 6e 20 4c 53 4d 5f 49  d ) return LSM_I
1880: 4f 45 52 52 3b 0a 0a 20 20 69 66 28 20 70 44 62  OERR;..  if( pDb
1890: 2d 3e 62 50 72 65 70 61 72 65 43 72 61 73 68 20  ->bPrepareCrash 
18a0: 29 7b 0a 20 20 20 20 46 69 6c 65 44 61 74 61 20  ){.    FileData 
18b0: 2a 70 44 61 74 61 20 3d 20 26 70 44 62 2d 3e 61  *pData = &pDb->a
18c0: 46 69 6c 65 5b 70 2d 3e 62 4c 6f 67 5d 3b 0a 20  File[p->bLog];. 
18d0: 20 20 20 69 6e 74 20 69 46 69 72 73 74 3b 20 20     int iFirst;  
18e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 0a                 .
18f0: 20 20 20 20 69 6e 74 20 69 4c 61 73 74 3b 0a 20      int iLast;. 
1900: 20 20 20 69 6e 74 20 69 53 65 63 74 6f 72 3b 0a     int iSector;.
1910: 0a 20 20 20 20 69 46 69 72 73 74 20 3d 20 28 69  .    iFirst = (i
1920: 4f 66 66 20 2f 20 70 44 62 2d 3e 73 7a 53 65 63  Off / pDb->szSec
1930: 74 6f 72 29 3b 0a 20 20 20 20 69 4c 61 73 74 20  tor);.    iLast 
1940: 3d 20 20 28 28 69 4f 66 66 20 2b 20 6e 44 61 74  =  ((iOff + nDat
1950: 61 20 2d 20 31 29 20 2f 20 70 44 62 2d 3e 73 7a  a - 1) / pDb->sz
1960: 53 65 63 74 6f 72 29 3b 0a 0a 20 20 20 20 69 66  Sector);..    if
1970: 28 20 70 44 61 74 61 2d 3e 6e 53 65 63 74 6f 72  ( pData->nSector
1980: 3c 28 69 4c 61 73 74 2b 31 29 20 29 7b 0a 20 20  <(iLast+1) ){.  
1990: 20 20 20 20 69 6e 74 20 6e 4e 65 77 20 3d 20 28      int nNew = (
19a0: 20 28 28 69 4c 61 73 74 20 2b 20 31 29 20 2b 20   ((iLast + 1) + 
19b0: 36 33 29 20 2f 20 36 34 20 29 20 2a 20 36 34 3b  63) / 64 ) * 64;
19c0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6e  .      assert( n
19d0: 4e 65 77 3e 69 4c 61 73 74 20 29 3b 0a 20 20 20  New>iLast );.   
19e0: 20 20 20 70 44 61 74 61 2d 3e 61 53 65 63 74 6f     pData->aSecto
19f0: 72 20 3d 20 28 46 69 6c 65 53 65 63 74 6f 72 20  r = (FileSector 
1a00: 2a 29 74 65 73 74 52 65 61 6c 6c 6f 63 28 0a 20  *)testRealloc(. 
1a10: 20 20 20 20 20 20 20 20 20 70 44 61 74 61 2d 3e           pData->
1a20: 61 53 65 63 74 6f 72 2c 20 6e 4e 65 77 2a 73 69  aSector, nNew*si
1a30: 7a 65 6f 66 28 46 69 6c 65 53 65 63 74 6f 72 29  zeof(FileSector)
1a40: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20  .      );.      
1a50: 6d 65 6d 73 65 74 28 26 70 44 61 74 61 2d 3e 61  memset(&pData->a
1a60: 53 65 63 74 6f 72 5b 70 44 61 74 61 2d 3e 6e 53  Sector[pData->nS
1a70: 65 63 74 6f 72 5d 2c 20 0a 20 20 20 20 20 20 20  ector], .       
1a80: 20 20 20 30 2c 20 28 6e 4e 65 77 20 2d 20 70 44     0, (nNew - pD
1a90: 61 74 61 2d 3e 6e 53 65 63 74 6f 72 29 20 2a 20  ata->nSector) * 
1aa0: 73 69 7a 65 6f 66 28 46 69 6c 65 53 65 63 74 6f  sizeof(FileSecto
1ab0: 72 29 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20  r).      );.    
1ac0: 20 20 70 44 61 74 61 2d 3e 6e 53 65 63 74 6f 72    pData->nSector
1ad0: 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 7d 0a 0a   = nNew;.    }..
1ae0: 20 20 20 20 66 6f 72 28 69 53 65 63 74 6f 72 3d      for(iSector=
1af0: 69 46 69 72 73 74 3b 20 69 53 65 63 74 6f 72 3c  iFirst; iSector<
1b00: 3d 69 4c 61 73 74 3b 20 69 53 65 63 74 6f 72 2b  =iLast; iSector+
1b10: 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 44  +){.      if( pD
1b20: 61 74 61 2d 3e 61 53 65 63 74 6f 72 5b 69 53 65  ata->aSector[iSe
1b30: 63 74 6f 72 5d 2e 61 4f 6c 64 3d 3d 30 20 29 7b  ctor].aOld==0 ){
1b40: 0a 20 20 20 20 20 20 20 20 75 38 20 2a 61 4f 6c  .        u8 *aOl
1b50: 64 20 3d 20 28 75 38 20 2a 29 74 65 73 74 4d 61  d = (u8 *)testMa
1b60: 6c 6c 6f 63 28 70 44 62 2d 3e 73 7a 53 65 63 74  lloc(pDb->szSect
1b70: 6f 72 29 3b 0a 20 20 20 20 20 20 20 20 70 52 65  or);.        pRe
1b80: 61 6c 45 6e 76 2d 3e 78 52 65 61 64 28 0a 20 20  alEnv->xRead(.  
1b90: 20 20 20 20 20 20 20 20 20 20 70 2d 3e 70 52 65            p->pRe
1ba0: 61 6c 2c 20 28 6c 73 6d 5f 69 36 34 29 69 53 65  al, (lsm_i64)iSe
1bb0: 63 74 6f 72 2a 70 44 62 2d 3e 73 7a 53 65 63 74  ctor*pDb->szSect
1bc0: 6f 72 2c 20 61 4f 6c 64 2c 20 70 44 62 2d 3e 73  or, aOld, pDb->s
1bd0: 7a 53 65 63 74 6f 72 0a 20 20 20 20 20 20 20 20  zSector.        
1be0: 29 3b 0a 20 20 20 20 20 20 20 20 70 44 61 74 61  );.        pData
1bf0: 2d 3e 61 53 65 63 74 6f 72 5b 69 53 65 63 74 6f  ->aSector[iSecto
1c00: 72 5d 2e 61 4f 6c 64 20 3d 20 61 4f 6c 64 3b 0a  r].aOld = aOld;.
1c10: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
1c20: 7d 0a 0a 20 20 69 66 28 20 70 44 62 2d 3e 78 57  }..  if( pDb->xW
1c30: 72 69 74 65 48 6f 6f 6b 20 29 7b 0a 20 20 20 20  riteHook ){.    
1c40: 69 6e 74 20 72 63 3b 0a 20 20 20 20 69 6e 74 20  int rc;.    int 
1c50: 6e 55 73 3b 0a 20 20 20 20 73 74 72 75 63 74 20  nUs;.    struct 
1c60: 74 69 6d 65 76 61 6c 20 74 31 3b 0a 20 20 20 20  timeval t1;.    
1c70: 73 74 72 75 63 74 20 74 69 6d 65 76 61 6c 20 74  struct timeval t
1c80: 32 3b 0a 0a 20 20 20 20 67 65 74 74 69 6d 65 6f  2;..    gettimeo
1c90: 66 64 61 79 28 26 74 31 2c 20 30 29 3b 0a 20 20  fday(&t1, 0);.  
1ca0: 20 20 61 73 73 65 72 74 28 20 6e 44 61 74 61 3e    assert( nData>
1cb0: 30 20 29 3b 0a 20 20 20 20 72 63 20 3d 20 70 52  0 );.    rc = pR
1cc0: 65 61 6c 45 6e 76 2d 3e 78 57 72 69 74 65 28 70  ealEnv->xWrite(p
1cd0: 2d 3e 70 52 65 61 6c 2c 20 69 4f 66 66 2c 20 70  ->pReal, iOff, p
1ce0: 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20  Data, nData);.  
1cf0: 20 20 67 65 74 74 69 6d 65 6f 66 64 61 79 28 26    gettimeofday(&
1d00: 74 32 2c 20 30 29 3b 0a 0a 20 20 20 20 6e 55 73  t2, 0);..    nUs
1d10: 20 3d 20 28 74 32 2e 74 76 5f 73 65 63 20 2d 20   = (t2.tv_sec - 
1d20: 74 31 2e 74 76 5f 73 65 63 29 20 2a 20 31 30 30  t1.tv_sec) * 100
1d30: 30 30 30 30 20 2b 20 28 74 32 2e 74 76 5f 75 73  0000 + (t2.tv_us
1d40: 65 63 20 2d 20 74 31 2e 74 76 5f 75 73 65 63 29  ec - t1.tv_usec)
1d50: 3b 0a 20 20 20 20 70 44 62 2d 3e 78 57 72 69 74  ;.    pDb->xWrit
1d60: 65 48 6f 6f 6b 28 70 44 62 2d 3e 70 57 72 69 74  eHook(pDb->pWrit
1d70: 65 43 74 78 2c 20 70 2d 3e 62 4c 6f 67 2c 20 69  eCtx, p->bLog, i
1d80: 4f 66 66 2c 20 6e 44 61 74 61 2c 20 6e 55 73 29  Off, nData, nUs)
1d90: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b  ;.    return rc;
1da0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 70  .  }..  return p
1db0: 52 65 61 6c 45 6e 76 2d 3e 78 57 72 69 74 65 28  RealEnv->xWrite(
1dc0: 70 2d 3e 70 52 65 61 6c 2c 20 69 4f 66 66 2c 20  p->pReal, iOff, 
1dd0: 70 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 7d  pData, nData);.}
1de0: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f  ..static void do
1df0: 53 79 73 74 65 6d 43 72 61 73 68 28 4c 73 6d 44  SystemCrash(LsmD
1e00: 62 20 2a 70 44 62 29 3b 0a 0a 73 74 61 74 69 63  b *pDb);..static
1e10: 20 69 6e 74 20 74 65 73 74 45 6e 76 53 79 6e 63   int testEnvSync
1e20: 28 6c 73 6d 5f 66 69 6c 65 20 2a 70 46 69 6c 65  (lsm_file *pFile
1e30: 29 7b 0a 20 20 6c 73 6d 5f 65 6e 76 20 2a 70 52  ){.  lsm_env *pR
1e40: 65 61 6c 45 6e 76 20 3d 20 74 64 62 5f 6c 73 6d  ealEnv = tdb_lsm
1e50: 5f 65 6e 76 28 29 3b 0a 20 20 4c 73 6d 46 69 6c  _env();.  LsmFil
1e60: 65 20 2a 70 20 3d 20 28 4c 73 6d 46 69 6c 65 20  e *p = (LsmFile 
1e70: 2a 29 70 46 69 6c 65 3b 0a 20 20 4c 73 6d 44 62  *)pFile;.  LsmDb
1e80: 20 2a 70 44 62 20 3d 20 70 2d 3e 70 44 62 3b 0a   *pDb = p->pDb;.
1e90: 20 20 46 69 6c 65 44 61 74 61 20 2a 70 44 61 74    FileData *pDat
1ea0: 61 20 3d 20 26 70 44 62 2d 3e 61 46 69 6c 65 5b  a = &pDb->aFile[
1eb0: 70 2d 3e 62 4c 6f 67 5d 3b 0a 20 20 69 6e 74 20  p->bLog];.  int 
1ec0: 69 3b 0a 0a 20 20 69 66 28 20 70 44 62 2d 3e 62  i;..  if( pDb->b
1ed0: 43 72 61 73 68 65 64 20 29 20 72 65 74 75 72 6e  Crashed ) return
1ee0: 20 4c 53 4d 5f 49 4f 45 52 52 3b 0a 0a 20 20 69   LSM_IOERR;..  i
1ef0: 66 28 20 70 44 62 2d 3e 6e 41 75 74 6f 43 72 61  f( pDb->nAutoCra
1f00: 73 68 20 29 7b 0a 20 20 20 20 70 44 62 2d 3e 6e  sh ){.    pDb->n
1f10: 41 75 74 6f 43 72 61 73 68 2d 2d 3b 0a 20 20 20  AutoCrash--;.   
1f20: 20 69 66 28 20 70 44 62 2d 3e 6e 41 75 74 6f 43   if( pDb->nAutoC
1f30: 72 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20 20  rash==0 ){.     
1f40: 20 64 6f 53 79 73 74 65 6d 43 72 61 73 68 28 70   doSystemCrash(p
1f50: 44 62 29 3b 0a 20 20 20 20 20 20 70 44 62 2d 3e  Db);.      pDb->
1f60: 62 43 72 61 73 68 65 64 20 3d 20 31 3b 0a 20 20  bCrashed = 1;.  
1f70: 20 20 20 20 72 65 74 75 72 6e 20 4c 53 4d 5f 49      return LSM_I
1f80: 4f 45 52 52 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  OERR;.    }.  }.
1f90: 0a 20 20 69 66 28 20 70 44 62 2d 3e 62 50 72 65  .  if( pDb->bPre
1fa0: 70 61 72 65 43 72 61 73 68 20 29 7b 0a 20 20 20  pareCrash ){.   
1fb0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 44 61 74   for(i=0; i<pDat
1fc0: 61 2d 3e 6e 53 65 63 74 6f 72 3b 20 69 2b 2b 29  a->nSector; i++)
1fd0: 7b 0a 20 20 20 20 20 20 74 65 73 74 46 72 65 65  {.      testFree
1fe0: 28 70 44 61 74 61 2d 3e 61 53 65 63 74 6f 72 5b  (pData->aSector[
1ff0: 69 5d 2e 61 4f 6c 64 29 3b 0a 20 20 20 20 20 20  i].aOld);.      
2000: 70 44 61 74 61 2d 3e 61 53 65 63 74 6f 72 5b 69  pData->aSector[i
2010: 5d 2e 61 4f 6c 64 20 3d 20 30 3b 0a 20 20 20 20  ].aOld = 0;.    
2020: 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 44 62  }.  }..  if( pDb
2030: 2d 3e 78 57 72 69 74 65 48 6f 6f 6b 20 29 7b 0a  ->xWriteHook ){.
2040: 20 20 20 20 69 6e 74 20 72 63 3b 0a 20 20 20 20      int rc;.    
2050: 69 6e 74 20 6e 55 73 3b 0a 20 20 20 20 73 74 72  int nUs;.    str
2060: 75 63 74 20 74 69 6d 65 76 61 6c 20 74 31 3b 0a  uct timeval t1;.
2070: 20 20 20 20 73 74 72 75 63 74 20 74 69 6d 65 76      struct timev
2080: 61 6c 20 74 32 3b 0a 0a 20 20 20 20 67 65 74 74  al t2;..    gett
2090: 69 6d 65 6f 66 64 61 79 28 26 74 31 2c 20 30 29  imeofday(&t1, 0)
20a0: 3b 0a 20 20 20 20 72 63 20 3d 20 70 52 65 61 6c  ;.    rc = pReal
20b0: 45 6e 76 2d 3e 78 53 79 6e 63 28 70 2d 3e 70 52  Env->xSync(p->pR
20c0: 65 61 6c 29 3b 0a 20 20 20 20 67 65 74 74 69 6d  eal);.    gettim
20d0: 65 6f 66 64 61 79 28 26 74 32 2c 20 30 29 3b 0a  eofday(&t2, 0);.
20e0: 0a 20 20 20 20 6e 55 73 20 3d 20 28 74 32 2e 74  .    nUs = (t2.t
20f0: 76 5f 73 65 63 20 2d 20 74 31 2e 74 76 5f 73 65  v_sec - t1.tv_se
2100: 63 29 20 2a 20 31 30 30 30 30 30 30 20 2b 20 28  c) * 1000000 + (
2110: 74 32 2e 74 76 5f 75 73 65 63 20 2d 20 74 31 2e  t2.tv_usec - t1.
2120: 74 76 5f 75 73 65 63 29 3b 0a 20 20 20 20 70 44  tv_usec);.    pD
2130: 62 2d 3e 78 57 72 69 74 65 48 6f 6f 6b 28 70 44  b->xWriteHook(pD
2140: 62 2d 3e 70 57 72 69 74 65 43 74 78 2c 20 70 2d  b->pWriteCtx, p-
2150: 3e 62 4c 6f 67 2c 20 30 2c 20 30 2c 20 6e 55 73  >bLog, 0, 0, nUs
2160: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  );.    return rc
2170: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
2180: 70 52 65 61 6c 45 6e 76 2d 3e 78 53 79 6e 63 28  pRealEnv->xSync(
2190: 70 2d 3e 70 52 65 61 6c 29 3b 0a 7d 0a 0a 73 74  p->pReal);.}..st
21a0: 61 74 69 63 20 69 6e 74 20 74 65 73 74 45 6e 76  atic int testEnv
21b0: 54 72 75 6e 63 61 74 65 28 6c 73 6d 5f 66 69 6c  Truncate(lsm_fil
21c0: 65 20 2a 70 46 69 6c 65 2c 20 6c 73 6d 5f 69 36  e *pFile, lsm_i6
21d0: 34 20 69 4f 66 66 29 7b 0a 20 20 6c 73 6d 5f 65  4 iOff){.  lsm_e
21e0: 6e 76 20 2a 70 52 65 61 6c 45 6e 76 20 3d 20 74  nv *pRealEnv = t
21f0: 64 62 5f 6c 73 6d 5f 65 6e 76 28 29 3b 0a 20 20  db_lsm_env();.  
2200: 4c 73 6d 46 69 6c 65 20 2a 70 20 3d 20 28 4c 73  LsmFile *p = (Ls
2210: 6d 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b 0a 20  mFile *)pFile;. 
2220: 20 69 66 28 20 70 2d 3e 70 44 62 2d 3e 62 43 72   if( p->pDb->bCr
2230: 61 73 68 65 64 20 29 20 72 65 74 75 72 6e 20 4c  ashed ) return L
2240: 53 4d 5f 49 4f 45 52 52 3b 0a 20 20 72 65 74 75  SM_IOERR;.  retu
2250: 72 6e 20 70 52 65 61 6c 45 6e 76 2d 3e 78 54 72  rn pRealEnv->xTr
2260: 75 6e 63 61 74 65 28 70 2d 3e 70 52 65 61 6c 2c  uncate(p->pReal,
2270: 20 69 4f 66 66 29 3b 0a 7d 0a 0a 73 74 61 74 69   iOff);.}..stati
2280: 63 20 69 6e 74 20 74 65 73 74 45 6e 76 53 65 63  c int testEnvSec
2290: 74 6f 72 53 69 7a 65 28 6c 73 6d 5f 66 69 6c 65  torSize(lsm_file
22a0: 20 2a 70 46 69 6c 65 29 7b 0a 20 20 6c 73 6d 5f   *pFile){.  lsm_
22b0: 65 6e 76 20 2a 70 52 65 61 6c 45 6e 76 20 3d 20  env *pRealEnv = 
22c0: 74 64 62 5f 6c 73 6d 5f 65 6e 76 28 29 3b 0a 20  tdb_lsm_env();. 
22d0: 20 4c 73 6d 46 69 6c 65 20 2a 70 20 3d 20 28 4c   LsmFile *p = (L
22e0: 73 6d 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b 0a  smFile *)pFile;.
22f0: 20 20 72 65 74 75 72 6e 20 70 52 65 61 6c 45 6e    return pRealEn
2300: 76 2d 3e 78 53 65 63 74 6f 72 53 69 7a 65 28 70  v->xSectorSize(p
2310: 2d 3e 70 52 65 61 6c 29 3b 0a 7d 0a 0a 73 74 61  ->pReal);.}..sta
2320: 74 69 63 20 69 6e 74 20 74 65 73 74 45 6e 76 52  tic int testEnvR
2330: 65 6d 61 70 28 0a 20 20 6c 73 6d 5f 66 69 6c 65  emap(.  lsm_file
2340: 20 2a 70 46 69 6c 65 2c 20 0a 20 20 6c 73 6d 5f   *pFile, .  lsm_
2350: 69 36 34 20 69 4d 69 6e 2c 20 0a 20 20 76 6f 69  i64 iMin, .  voi
2360: 64 20 2a 2a 70 70 4f 75 74 2c 0a 20 20 6c 73 6d  d **ppOut,.  lsm
2370: 5f 69 36 34 20 2a 70 6e 4f 75 74 0a 29 7b 0a 20  _i64 *pnOut.){. 
2380: 20 6c 73 6d 5f 65 6e 76 20 2a 70 52 65 61 6c 45   lsm_env *pRealE
2390: 6e 76 20 3d 20 74 64 62 5f 6c 73 6d 5f 65 6e 76  nv = tdb_lsm_env
23a0: 28 29 3b 0a 20 20 4c 73 6d 46 69 6c 65 20 2a 70  ();.  LsmFile *p
23b0: 20 3d 20 28 4c 73 6d 46 69 6c 65 20 2a 29 70 46   = (LsmFile *)pF
23c0: 69 6c 65 3b 0a 20 20 72 65 74 75 72 6e 20 70 52  ile;.  return pR
23d0: 65 61 6c 45 6e 76 2d 3e 78 52 65 6d 61 70 28 70  ealEnv->xRemap(p
23e0: 2d 3e 70 52 65 61 6c 2c 20 69 4d 69 6e 2c 20 70  ->pReal, iMin, p
23f0: 70 4f 75 74 2c 20 70 6e 4f 75 74 29 3b 0a 7d 0a  pOut, pnOut);.}.
2400: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74  .static int test
2410: 45 6e 76 46 69 6c 65 69 64 28 0a 20 20 6c 73 6d  EnvFileid(.  lsm
2420: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 0a 20  _file *pFile, . 
2430: 20 76 6f 69 64 20 2a 70 70 4f 75 74 2c 0a 20 20   void *ppOut,.  
2440: 69 6e 74 20 2a 70 6e 4f 75 74 0a 29 7b 0a 20 20  int *pnOut.){.  
2450: 6c 73 6d 5f 65 6e 76 20 2a 70 52 65 61 6c 45 6e  lsm_env *pRealEn
2460: 76 20 3d 20 74 64 62 5f 6c 73 6d 5f 65 6e 76 28  v = tdb_lsm_env(
2470: 29 3b 0a 20 20 4c 73 6d 46 69 6c 65 20 2a 70 20  );.  LsmFile *p 
2480: 3d 20 28 4c 73 6d 46 69 6c 65 20 2a 29 70 46 69  = (LsmFile *)pFi
2490: 6c 65 3b 0a 20 20 72 65 74 75 72 6e 20 70 52 65  le;.  return pRe
24a0: 61 6c 45 6e 76 2d 3e 78 46 69 6c 65 69 64 28 70  alEnv->xFileid(p
24b0: 2d 3e 70 52 65 61 6c 2c 20 70 70 4f 75 74 2c 20  ->pReal, ppOut, 
24c0: 70 6e 4f 75 74 29 3b 0a 7d 0a 0a 73 74 61 74 69  pnOut);.}..stati
24d0: 63 20 69 6e 74 20 74 65 73 74 45 6e 76 43 6c 6f  c int testEnvClo
24e0: 73 65 28 6c 73 6d 5f 66 69 6c 65 20 2a 70 46 69  se(lsm_file *pFi
24f0: 6c 65 29 7b 0a 20 20 6c 73 6d 5f 65 6e 76 20 2a  le){.  lsm_env *
2500: 70 52 65 61 6c 45 6e 76 20 3d 20 74 64 62 5f 6c  pRealEnv = tdb_l
2510: 73 6d 5f 65 6e 76 28 29 3b 0a 20 20 4c 73 6d 46  sm_env();.  LsmF
2520: 69 6c 65 20 2a 70 20 3d 20 28 4c 73 6d 46 69 6c  ile *p = (LsmFil
2530: 65 20 2a 29 70 46 69 6c 65 3b 0a 0a 20 20 70 52  e *)pFile;..  pR
2540: 65 61 6c 45 6e 76 2d 3e 78 43 6c 6f 73 65 28 70  ealEnv->xClose(p
2550: 2d 3e 70 52 65 61 6c 29 3b 0a 20 20 74 65 73 74  ->pReal);.  test
2560: 46 72 65 65 28 70 29 3b 0a 20 20 72 65 74 75 72  Free(p);.  retur
2570: 6e 20 4c 53 4d 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61  n LSM_OK;.}..sta
2580: 74 69 63 20 69 6e 74 20 74 65 73 74 45 6e 76 55  tic int testEnvU
2590: 6e 6c 69 6e 6b 28 6c 73 6d 5f 65 6e 76 20 2a 70  nlink(lsm_env *p
25a0: 45 6e 76 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  Env, const char 
25b0: 2a 7a 46 69 6c 65 29 7b 0a 20 20 6c 73 6d 5f 65  *zFile){.  lsm_e
25c0: 6e 76 20 2a 70 52 65 61 6c 45 6e 76 20 3d 20 74  nv *pRealEnv = t
25d0: 64 62 5f 6c 73 6d 5f 65 6e 76 28 29 3b 0a 20 20  db_lsm_env();.  
25e0: 75 6e 75 73 65 64 5f 70 61 72 61 6d 65 74 65 72  unused_parameter
25f0: 28 70 45 6e 76 29 3b 0a 20 20 72 65 74 75 72 6e  (pEnv);.  return
2600: 20 70 52 65 61 6c 45 6e 76 2d 3e 78 55 6e 6c 69   pRealEnv->xUnli
2610: 6e 6b 28 70 52 65 61 6c 45 6e 76 2c 20 7a 46 69  nk(pRealEnv, zFi
2620: 6c 65 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  le);.}..static i
2630: 6e 74 20 74 65 73 74 45 6e 76 4c 6f 63 6b 28 6c  nt testEnvLock(l
2640: 73 6d 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20  sm_file *pFile, 
2650: 69 6e 74 20 69 4c 6f 63 6b 2c 20 69 6e 74 20 65  int iLock, int e
2660: 54 79 70 65 29 7b 0a 20 20 4c 73 6d 46 69 6c 65  Type){.  LsmFile
2670: 20 2a 70 20 3d 20 28 4c 73 6d 46 69 6c 65 20 2a   *p = (LsmFile *
2680: 29 70 46 69 6c 65 3b 0a 20 20 6c 73 6d 5f 65 6e  )pFile;.  lsm_en
2690: 76 20 2a 70 52 65 61 6c 45 6e 76 20 3d 20 74 64  v *pRealEnv = td
26a0: 62 5f 6c 73 6d 5f 65 6e 76 28 29 3b 0a 0a 20 20  b_lsm_env();..  
26b0: 69 66 28 20 69 4c 6f 63 6b 3d 3d 32 20 26 26 20  if( iLock==2 && 
26c0: 65 54 79 70 65 3d 3d 4c 53 4d 5f 4c 4f 43 4b 5f  eType==LSM_LOCK_
26d0: 45 58 43 4c 20 26 26 20 70 2d 3e 70 44 62 2d 3e  EXCL && p->pDb->
26e0: 62 4e 6f 52 65 63 6f 76 65 72 79 20 29 7b 0a 20  bNoRecovery ){. 
26f0: 20 20 20 72 65 74 75 72 6e 20 4c 53 4d 5f 42 55     return LSM_BU
2700: 53 59 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  SY;.  }.  return
2710: 20 70 52 65 61 6c 45 6e 76 2d 3e 78 4c 6f 63 6b   pRealEnv->xLock
2720: 28 70 2d 3e 70 52 65 61 6c 2c 20 69 4c 6f 63 6b  (p->pReal, iLock
2730: 2c 20 65 54 79 70 65 29 3b 0a 7d 0a 0a 73 74 61  , eType);.}..sta
2740: 74 69 63 20 69 6e 74 20 74 65 73 74 45 6e 76 54  tic int testEnvT
2750: 65 73 74 4c 6f 63 6b 28 6c 73 6d 5f 66 69 6c 65  estLock(lsm_file
2760: 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 69 4c 6f   *pFile, int iLo
2770: 63 6b 2c 20 69 6e 74 20 6e 4c 6f 63 6b 2c 20 69  ck, int nLock, i
2780: 6e 74 20 65 54 79 70 65 29 7b 0a 20 20 4c 73 6d  nt eType){.  Lsm
2790: 46 69 6c 65 20 2a 70 20 3d 20 28 4c 73 6d 46 69  File *p = (LsmFi
27a0: 6c 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20 6c 73  le *)pFile;.  ls
27b0: 6d 5f 65 6e 76 20 2a 70 52 65 61 6c 45 6e 76 20  m_env *pRealEnv 
27c0: 3d 20 74 64 62 5f 6c 73 6d 5f 65 6e 76 28 29 3b  = tdb_lsm_env();
27d0: 0a 0a 20 20 69 66 28 20 69 4c 6f 63 6b 3d 3d 32  ..  if( iLock==2
27e0: 20 26 26 20 65 54 79 70 65 3d 3d 4c 53 4d 5f 4c   && eType==LSM_L
27f0: 4f 43 4b 5f 45 58 43 4c 20 26 26 20 70 2d 3e 70  OCK_EXCL && p->p
2800: 44 62 2d 3e 62 4e 6f 52 65 63 6f 76 65 72 79 20  Db->bNoRecovery 
2810: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 4c 53  ){.    return LS
2820: 4d 5f 42 55 53 59 3b 0a 20 20 7d 0a 20 20 72 65  M_BUSY;.  }.  re
2830: 74 75 72 6e 20 70 52 65 61 6c 45 6e 76 2d 3e 78  turn pRealEnv->x
2840: 54 65 73 74 4c 6f 63 6b 28 70 2d 3e 70 52 65 61  TestLock(p->pRea
2850: 6c 2c 20 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 2c  l, iLock, nLock,
2860: 20 65 54 79 70 65 29 3b 0a 7d 0a 0a 73 74 61 74   eType);.}..stat
2870: 69 63 20 69 6e 74 20 74 65 73 74 45 6e 76 53 68  ic int testEnvSh
2880: 6d 4d 61 70 28 6c 73 6d 5f 66 69 6c 65 20 2a 70  mMap(lsm_file *p
2890: 46 69 6c 65 2c 20 69 6e 74 20 69 52 65 67 69 6f  File, int iRegio
28a0: 6e 2c 20 69 6e 74 20 73 7a 2c 20 76 6f 69 64 20  n, int sz, void 
28b0: 2a 2a 70 70 29 7b 0a 20 20 4c 73 6d 46 69 6c 65  **pp){.  LsmFile
28c0: 20 2a 70 20 3d 20 28 4c 73 6d 46 69 6c 65 20 2a   *p = (LsmFile *
28d0: 29 70 46 69 6c 65 3b 0a 20 20 6c 73 6d 5f 65 6e  )pFile;.  lsm_en
28e0: 76 20 2a 70 52 65 61 6c 45 6e 76 20 3d 20 74 64  v *pRealEnv = td
28f0: 62 5f 6c 73 6d 5f 65 6e 76 28 29 3b 0a 20 20 72  b_lsm_env();.  r
2900: 65 74 75 72 6e 20 70 52 65 61 6c 45 6e 76 2d 3e  eturn pRealEnv->
2910: 78 53 68 6d 4d 61 70 28 70 2d 3e 70 52 65 61 6c  xShmMap(p->pReal
2920: 2c 20 69 52 65 67 69 6f 6e 2c 20 73 7a 2c 20 70  , iRegion, sz, p
2930: 70 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  p);.}..static vo
2940: 69 64 20 74 65 73 74 45 6e 76 53 68 6d 42 61 72  id testEnvShmBar
2950: 72 69 65 72 28 76 6f 69 64 29 7b 0a 7d 0a 0a 73  rier(void){.}..s
2960: 74 61 74 69 63 20 69 6e 74 20 74 65 73 74 45 6e  tatic int testEn
2970: 76 53 68 6d 55 6e 6d 61 70 28 6c 73 6d 5f 66 69  vShmUnmap(lsm_fi
2980: 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 62  le *pFile, int b
2990: 44 65 6c 29 7b 0a 20 20 4c 73 6d 46 69 6c 65 20  Del){.  LsmFile 
29a0: 2a 70 20 3d 20 28 4c 73 6d 46 69 6c 65 20 2a 29  *p = (LsmFile *)
29b0: 70 46 69 6c 65 3b 0a 20 20 6c 73 6d 5f 65 6e 76  pFile;.  lsm_env
29c0: 20 2a 70 52 65 61 6c 45 6e 76 20 3d 20 74 64 62   *pRealEnv = tdb
29d0: 5f 6c 73 6d 5f 65 6e 76 28 29 3b 0a 20 20 72 65  _lsm_env();.  re
29e0: 74 75 72 6e 20 70 52 65 61 6c 45 6e 76 2d 3e 78  turn pRealEnv->x
29f0: 53 68 6d 55 6e 6d 61 70 28 70 2d 3e 70 52 65 61  ShmUnmap(p->pRea
2a00: 6c 2c 20 62 44 65 6c 29 3b 0a 7d 0a 0a 73 74 61  l, bDel);.}..sta
2a10: 74 69 63 20 69 6e 74 20 74 65 73 74 45 6e 76 53  tic int testEnvS
2a20: 6c 65 65 70 28 6c 73 6d 5f 65 6e 76 20 2a 70 45  leep(lsm_env *pE
2a30: 6e 76 2c 20 69 6e 74 20 75 73 29 7b 0a 20 20 6c  nv, int us){.  l
2a40: 73 6d 5f 65 6e 76 20 2a 70 52 65 61 6c 45 6e 76  sm_env *pRealEnv
2a50: 20 3d 20 74 64 62 5f 6c 73 6d 5f 65 6e 76 28 29   = tdb_lsm_env()
2a60: 3b 0a 20 20 72 65 74 75 72 6e 20 70 52 65 61 6c  ;.  return pReal
2a70: 45 6e 76 2d 3e 78 53 6c 65 65 70 28 70 52 65 61  Env->xSleep(pRea
2a80: 6c 45 6e 76 2c 20 75 73 29 3b 0a 7d 0a 0a 73 74  lEnv, us);.}..st
2a90: 61 74 69 63 20 76 6f 69 64 20 64 6f 53 79 73 74  atic void doSyst
2aa0: 65 6d 43 72 61 73 68 28 4c 73 6d 44 62 20 2a 70  emCrash(LsmDb *p
2ab0: 44 62 29 7b 0a 20 20 6c 73 6d 5f 65 6e 76 20 2a  Db){.  lsm_env *
2ac0: 70 45 6e 76 20 3d 20 74 64 62 5f 6c 73 6d 5f 65  pEnv = tdb_lsm_e
2ad0: 6e 76 28 29 3b 0a 20 20 69 6e 74 20 69 46 69 6c  nv();.  int iFil
2ae0: 65 3b 0a 20 20 69 6e 74 20 69 53 65 65 64 20 3d  e;.  int iSeed =
2af0: 20 70 44 62 2d 3e 61 46 69 6c 65 5b 30 5d 2e 6e   pDb->aFile[0].n
2b00: 53 65 63 74 6f 72 20 2b 20 70 44 62 2d 3e 61 46  Sector + pDb->aF
2b10: 69 6c 65 5b 31 5d 2e 6e 53 65 63 74 6f 72 3b 0a  ile[1].nSector;.
2b20: 0a 20 20 63 68 61 72 20 2a 7a 46 69 6c 65 20 3d  .  char *zFile =
2b30: 20 70 44 62 2d 3e 7a 4e 61 6d 65 3b 0a 20 20 63   pDb->zName;.  c
2b40: 68 61 72 20 2a 7a 46 72 65 65 20 3d 20 30 3b 0a  har *zFree = 0;.
2b50: 0a 20 20 66 6f 72 28 69 46 69 6c 65 3d 30 3b 20  .  for(iFile=0; 
2b60: 69 46 69 6c 65 3c 32 3b 20 69 46 69 6c 65 2b 2b  iFile<2; iFile++
2b70: 29 7b 0a 20 20 20 20 6c 73 6d 5f 66 69 6c 65 20  ){.    lsm_file 
2b80: 2a 70 46 69 6c 65 20 3d 20 30 3b 0a 20 20 20 20  *pFile = 0;.    
2b90: 69 6e 74 20 69 3b 0a 0a 20 20 20 20 70 45 6e 76  int i;..    pEnv
2ba0: 2d 3e 78 4f 70 65 6e 28 70 45 6e 76 2c 20 7a 46  ->xOpen(pEnv, zF
2bb0: 69 6c 65 2c 20 30 2c 20 26 70 46 69 6c 65 29 3b  ile, 0, &pFile);
2bc0: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  .    for(i=0; i<
2bd0: 70 44 62 2d 3e 61 46 69 6c 65 5b 69 46 69 6c 65  pDb->aFile[iFile
2be0: 5d 2e 6e 53 65 63 74 6f 72 3b 20 69 2b 2b 29 7b  ].nSector; i++){
2bf0: 0a 20 20 20 20 20 20 75 38 20 2a 61 4f 6c 64 20  .      u8 *aOld 
2c00: 3d 20 70 44 62 2d 3e 61 46 69 6c 65 5b 69 46 69  = pDb->aFile[iFi
2c10: 6c 65 5d 2e 61 53 65 63 74 6f 72 5b 69 5d 2e 61  le].aSector[i].a
2c20: 4f 6c 64 3b 0a 20 20 20 20 20 20 69 66 28 20 61  Old;.      if( a
2c30: 4f 6c 64 20 29 7b 0a 20 20 20 20 20 20 20 20 69  Old ){.        i
2c40: 6e 74 20 69 4f 70 74 20 3d 20 74 65 73 74 50 72  nt iOpt = testPr
2c50: 6e 67 56 61 6c 75 65 28 69 53 65 65 64 2b 2b 29  ngValue(iSeed++)
2c60: 20 25 20 33 3b 0a 20 20 20 20 20 20 20 20 73 77   % 3;.        sw
2c70: 69 74 63 68 28 20 69 4f 70 74 20 29 7b 0a 20 20  itch( iOpt ){.  
2c80: 20 20 20 20 20 20 20 20 63 61 73 65 20 30 3a 0a          case 0:.
2c90: 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61              brea
2ca0: 6b 3b 0a 0a 20 20 20 20 20 20 20 20 20 20 63 61  k;..          ca
2cb0: 73 65 20 31 3a 0a 20 20 20 20 20 20 20 20 20 20  se 1:.          
2cc0: 20 20 74 65 73 74 50 72 6e 67 41 72 72 61 79 28    testPrngArray(
2cd0: 69 53 65 65 64 2b 2b 2c 20 28 75 33 32 20 2a 29  iSeed++, (u32 *)
2ce0: 61 4f 6c 64 2c 20 70 44 62 2d 3e 73 7a 53 65 63  aOld, pDb->szSec
2cf0: 74 6f 72 2f 34 29 3b 0a 20 20 20 20 20 20 20 20  tor/4);.        
2d00: 20 20 20 20 2f 2a 20 46 61 6c 6c 2d 74 68 72 6f      /* Fall-thro
2d10: 75 67 68 20 2a 2f 0a 0a 20 20 20 20 20 20 20 20  ugh */..        
2d20: 20 20 63 61 73 65 20 32 3a 0a 20 20 20 20 20 20    case 2:.      
2d30: 20 20 20 20 20 20 70 45 6e 76 2d 3e 78 57 72 69        pEnv->xWri
2d40: 74 65 28 0a 20 20 20 20 20 20 20 20 20 20 20 20  te(.            
2d50: 20 20 20 20 70 46 69 6c 65 2c 20 28 6c 73 6d 5f      pFile, (lsm_
2d60: 69 36 34 29 69 20 2a 20 70 44 62 2d 3e 73 7a 53  i64)i * pDb->szS
2d70: 65 63 74 6f 72 2c 20 61 4f 6c 64 2c 20 70 44 62  ector, aOld, pDb
2d80: 2d 3e 73 7a 53 65 63 74 6f 72 0a 20 20 20 20 20  ->szSector.     
2d90: 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20         );.      
2da0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
2db0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 74       }.        t
2dc0: 65 73 74 46 72 65 65 28 61 4f 6c 64 29 3b 0a 20  estFree(aOld);. 
2dd0: 20 20 20 20 20 20 20 70 44 62 2d 3e 61 46 69 6c         pDb->aFil
2de0: 65 5b 69 46 69 6c 65 5d 2e 61 53 65 63 74 6f 72  e[iFile].aSector
2df0: 5b 69 5d 2e 61 4f 6c 64 20 3d 20 30 3b 0a 20 20  [i].aOld = 0;.  
2e00: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
2e10: 70 45 6e 76 2d 3e 78 43 6c 6f 73 65 28 70 46 69  pEnv->xClose(pFi
2e20: 6c 65 29 3b 0a 20 20 20 20 7a 46 72 65 65 20 3d  le);.    zFree =
2e30: 20 7a 46 69 6c 65 20 3d 20 73 71 6c 69 74 65 33   zFile = sqlite3
2e40: 5f 6d 70 72 69 6e 74 66 28 22 25 73 2d 6c 6f 67  _mprintf("%s-log
2e50: 22 2c 20 70 44 62 2d 3e 7a 4e 61 6d 65 29 3b 0a  ", pDb->zName);.
2e60: 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 66    }..  sqlite3_f
2e70: 72 65 65 28 7a 46 72 65 65 29 3b 0a 7d 0a 2f 2a  ree(zFree);.}./*
2e80: 0a 2a 2a 20 45 6e 64 20 74 65 73 74 20 56 46 53  .** End test VFS
2e90: 20 63 6f 64 65 2e 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a   code..*********
2ea0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2eb0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2ec0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2ed0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2ee0: 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  *.**************
2ef0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a  ***********/../*
2f30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f70: 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a  ********.*******
2f80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2fa0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2fb0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2fc0: 2a 2a 2a 0a 2a 2a 20 42 65 67 69 6e 20 74 65 73  ***.** Begin tes
2fd0: 74 20 63 6f 6d 70 72 65 73 73 69 6f 6e 20 68 6f  t compression ho
2fe0: 6f 6b 73 2e 0a 2a 2f 0a 0a 23 69 66 64 65 66 20  oks..*/..#ifdef 
2ff0: 48 41 56 45 5f 5a 4c 49 42 0a 23 69 6e 63 6c 75  HAVE_ZLIB.#inclu
3000: 64 65 20 3c 7a 6c 69 62 2e 68 3e 0a 0a 73 74 61  de <zlib.h>..sta
3010: 74 69 63 20 69 6e 74 20 74 65 73 74 5a 69 70 42  tic int testZipB
3020: 6f 75 6e 64 28 76 6f 69 64 20 2a 70 43 74 78 2c  ound(void *pCtx,
3030: 20 69 6e 74 20 6e 53 72 63 29 7b 0a 20 20 72 65   int nSrc){.  re
3040: 74 75 72 6e 20 63 6f 6d 70 72 65 73 73 42 6f 75  turn compressBou
3050: 6e 64 28 6e 53 72 63 29 3b 0a 7d 0a 0a 73 74 61  nd(nSrc);.}..sta
3060: 74 69 63 20 69 6e 74 20 74 65 73 74 5a 69 70 43  tic int testZipC
3070: 6f 6d 70 72 65 73 73 28 0a 20 20 76 6f 69 64 20  ompress(.  void 
3080: 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20  *pCtx,          
3090: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
30a0: 6e 74 65 78 74 20 70 6f 69 6e 74 65 72 20 2a 2f  ntext pointer */
30b0: 0a 20 20 63 68 61 72 20 2a 61 4f 75 74 2c 20 69  .  char *aOut, i
30c0: 6e 74 20 2a 70 6e 4f 75 74 2c 20 20 20 20 20 20  nt *pnOut,      
30d0: 20 20 20 2f 2a 20 4f 55 54 3a 20 42 75 66 66 65     /* OUT: Buffe
30e0: 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 63 6f 6d  r containing com
30f0: 70 72 65 73 73 65 64 20 64 61 74 61 20 2a 2f 0a  pressed data */.
3100: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 49    const char *aI
3110: 6e 2c 20 69 6e 74 20 6e 49 6e 20 20 20 20 20 20  n, int nIn      
3120: 20 20 2f 2a 20 42 75 66 66 65 72 20 63 6f 6e 74    /* Buffer cont
3130: 61 69 6e 69 6e 67 20 69 6e 70 75 74 20 64 61 74  aining input dat
3140: 61 20 2a 2f 0a 29 7b 0a 20 20 75 4c 6f 6e 67 66  a */.){.  uLongf
3150: 20 6e 20 3d 20 2a 70 6e 4f 75 74 3b 20 20 20 20   n = *pnOut;    
3160: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 2f            /* In/
3170: 6f 75 74 20 62 75 66 66 65 72 20 73 69 7a 65 20  out buffer size 
3180: 66 6f 72 20 63 6f 6d 70 72 65 73 73 28 29 20 2a  for compress() *
3190: 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  /.  int rc;     
31a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
31b0: 20 20 20 20 2f 2a 20 63 6f 6d 70 72 65 73 73 28      /* compress(
31c0: 29 20 72 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  ) return code */
31d0: 0a 20 0a 20 20 72 63 20 3d 20 63 6f 6d 70 72 65  . .  rc = compre
31e0: 73 73 28 28 42 79 74 65 66 2a 29 61 4f 75 74 2c  ss((Bytef*)aOut,
31f0: 20 26 6e 2c 20 28 42 79 74 65 66 2a 29 61 49 6e   &n, (Bytef*)aIn
3200: 2c 20 6e 49 6e 29 3b 0a 20 20 2a 70 6e 4f 75 74  , nIn);.  *pnOut
3210: 20 3d 20 6e 3b 0a 20 20 72 65 74 75 72 6e 20 28   = n;.  return (
3220: 72 63 3d 3d 5a 5f 4f 4b 20 3f 20 30 20 3a 20 4c  rc==Z_OK ? 0 : L
3230: 53 4d 5f 45 52 52 4f 52 29 3b 0a 7d 0a 0a 73 74  SM_ERROR);.}..st
3240: 61 74 69 63 20 69 6e 74 20 74 65 73 74 5a 69 70  atic int testZip
3250: 55 6e 63 6f 6d 70 72 65 73 73 28 0a 20 20 76 6f  Uncompress(.  vo
3260: 69 64 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20  id *pCtx,       
3270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3280: 20 43 6f 6e 74 65 78 74 20 70 6f 69 6e 74 65 72   Context pointer
3290: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 61 4f 75 74   */.  char *aOut
32a0: 2c 20 69 6e 74 20 2a 70 6e 4f 75 74 2c 20 20 20  , int *pnOut,   
32b0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 42 75        /* OUT: Bu
32c0: 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ffer containing 
32d0: 75 6e 63 6f 6d 70 72 65 73 73 65 64 20 64 61 74  uncompressed dat
32e0: 61 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  a */.  const cha
32f0: 72 20 2a 61 49 6e 2c 20 69 6e 74 20 6e 49 6e 20  r *aIn, int nIn 
3300: 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72         /* Buffer
3310: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 69 6e 70 75   containing inpu
3320: 74 20 64 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 75  t data */.){.  u
3330: 4c 6f 6e 67 66 20 6e 20 3d 20 2a 70 6e 4f 75 74  Longf n = *pnOut
3340: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
3350: 2a 20 49 6e 2f 6f 75 74 20 62 75 66 66 65 72 20  * In/out buffer 
3360: 73 69 7a 65 20 66 6f 72 20 75 6e 63 6f 6d 70 72  size for uncompr
3370: 65 73 73 28 29 20 2a 2f 0a 20 20 69 6e 74 20 72  ess() */.  int r
3380: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
3390: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 75 6e             /* un
33a0: 63 6f 6d 70 72 65 73 73 28 29 20 72 65 74 75 72  compress() retur
33b0: 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 72 63 20  n code */..  rc 
33c0: 3d 20 75 6e 63 6f 6d 70 72 65 73 73 28 28 42 79  = uncompress((By
33d0: 74 65 66 2a 29 61 4f 75 74 2c 20 26 6e 2c 20 28  tef*)aOut, &n, (
33e0: 42 79 74 65 66 2a 29 61 49 6e 2c 20 6e 49 6e 29  Bytef*)aIn, nIn)
33f0: 3b 0a 20 20 2a 70 6e 4f 75 74 20 3d 20 6e 3b 0a  ;.  *pnOut = n;.
3400: 20 20 72 65 74 75 72 6e 20 28 72 63 3d 3d 5a 5f    return (rc==Z_
3410: 4f 4b 20 3f 20 30 20 3a 20 4c 53 4d 5f 45 52 52  OK ? 0 : LSM_ERR
3420: 4f 52 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  OR);.}..static i
3430: 6e 74 20 74 65 73 74 43 6f 6e 66 69 67 75 72 65  nt testConfigure
3440: 43 6f 6d 70 72 65 73 73 69 6f 6e 28 6c 73 6d 5f  Compression(lsm_
3450: 64 62 20 2a 70 44 62 29 7b 0a 20 20 73 74 61 74  db *pDb){.  stat
3460: 69 63 20 6c 73 6d 5f 63 6f 6d 70 72 65 73 73 20  ic lsm_compress 
3470: 7a 69 70 20 3d 20 7b 0a 20 20 20 20 30 2c 20 20  zip = {.    0,  
3480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3490: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e            /* Con
34a0: 74 65 78 74 20 70 6f 69 6e 74 65 72 20 28 75 6e  text pointer (un
34b0: 75 73 65 64 29 20 2a 2f 0a 20 20 20 20 31 2c 20  used) */.    1, 
34c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 64             /* Id
34e0: 20 76 61 6c 75 65 20 2a 2f 0a 20 20 20 20 74 65   value */.    te
34f0: 73 74 5a 69 70 42 6f 75 6e 64 2c 20 20 20 20 20  stZipBound,     
3500: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
3510: 42 6f 75 6e 64 20 6d 65 74 68 6f 64 20 2a 2f 0a  Bound method */.
3520: 20 20 20 20 74 65 73 74 5a 69 70 43 6f 6d 70 72      testZipCompr
3530: 65 73 73 2c 20 20 20 20 20 20 20 20 20 20 20 20  ess,            
3540: 20 20 2f 2a 20 78 43 6f 6d 70 72 65 73 73 20 6d    /* xCompress m
3550: 65 74 68 6f 64 20 2a 2f 0a 20 20 20 20 74 65 73  ethod */.    tes
3560: 74 5a 69 70 55 6e 63 6f 6d 70 72 65 73 73 20 20  tZipUncompress  
3570: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55             /* xU
3580: 6e 63 6f 6d 70 72 65 73 73 20 6d 65 74 68 6f 64  ncompress method
3590: 20 2a 2f 0a 20 20 7d 3b 0a 20 20 72 65 74 75 72   */.  };.  retur
35a0: 6e 20 6c 73 6d 5f 63 6f 6e 66 69 67 28 70 44 62  n lsm_config(pDb
35b0: 2c 20 4c 53 4d 5f 43 4f 4e 46 49 47 5f 53 45 54  , LSM_CONFIG_SET
35c0: 5f 43 4f 4d 50 52 45 53 53 49 4f 4e 2c 20 26 7a  _COMPRESSION, &z
35d0: 69 70 29 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a  ip);.}.#endif /*
35e0: 20 69 66 64 65 66 20 48 41 56 45 5f 5a 4c 49 42   ifdef HAVE_ZLIB
35f0: 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 45 6e 64 20 74   */../*.** End t
3600: 65 73 74 20 63 6f 6d 70 72 65 73 73 69 6f 6e 20  est compression 
3610: 68 6f 6f 6b 73 2e 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  hooks..*********
3620: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3630: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3640: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3650: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3660: 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  *.**************
3670: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3680: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3690: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
36a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 73 74  ***********/..st
36b0: 61 74 69 63 20 69 6e 74 20 74 65 73 74 5f 6c 73  atic int test_ls
36c0: 6d 5f 63 6c 6f 73 65 28 54 65 73 74 44 62 20 2a  m_close(TestDb *
36d0: 70 54 65 73 74 44 62 29 7b 0a 20 20 69 6e 74 20  pTestDb){.  int 
36e0: 69 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53  i;.  int rc = LS
36f0: 4d 5f 4f 4b 3b 0a 20 20 4c 73 6d 44 62 20 2a 70  M_OK;.  LsmDb *p
3700: 44 62 20 3d 20 28 4c 73 6d 44 62 20 2a 29 70 54  Db = (LsmDb *)pT
3710: 65 73 74 44 62 3b 0a 0a 20 20 6c 73 6d 5f 63 73  estDb;..  lsm_cs
3720: 72 5f 63 6c 6f 73 65 28 70 44 62 2d 3e 70 43 73  r_close(pDb->pCs
3730: 72 29 3b 0a 20 20 6c 73 6d 5f 63 6c 6f 73 65 28  r);.  lsm_close(
3740: 70 44 62 2d 3e 64 62 29 3b 0a 0a 20 20 2f 2a 20  pDb->db);..  /* 
3750: 49 66 20 74 68 69 73 20 69 73 20 61 20 6d 75 6c  If this is a mul
3760: 74 69 2d 74 68 72 65 61 64 65 64 20 64 61 74 61  ti-threaded data
3770: 62 61 73 65 2c 20 77 61 69 74 20 6f 6e 20 74 68  base, wait on th
3780: 65 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73  e worker threads
3790: 2e 20 2a 2f 0a 20 20 6d 74 5f 73 68 75 74 64 6f  . */.  mt_shutdo
37a0: 77 6e 28 70 44 62 29 3b 0a 20 20 66 6f 72 28 69  wn(pDb);.  for(i
37b0: 3d 30 3b 20 69 3c 70 44 62 2d 3e 6e 57 6f 72 6b  =0; i<pDb->nWork
37c0: 65 72 20 26 26 20 72 63 3d 3d 4c 53 4d 5f 4f 4b  er && rc==LSM_OK
37d0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 72 63 20 3d  ; i++){.    rc =
37e0: 20 70 44 62 2d 3e 61 57 6f 72 6b 65 72 5b 69 5d   pDb->aWorker[i]
37f0: 2e 77 6f 72 6b 65 72 5f 72 63 3b 0a 20 20 7d 0a  .worker_rc;.  }.
3800: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 44  .  for(i=0; i<pD
3810: 62 2d 3e 61 46 69 6c 65 5b 30 5d 2e 6e 53 65 63  b->aFile[0].nSec
3820: 74 6f 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 74  tor; i++){.    t
3830: 65 73 74 46 72 65 65 28 70 44 62 2d 3e 61 46 69  estFree(pDb->aFi
3840: 6c 65 5b 30 5d 2e 61 53 65 63 74 6f 72 5b 69 5d  le[0].aSector[i]
3850: 2e 61 4f 6c 64 29 3b 0a 20 20 7d 0a 20 20 74 65  .aOld);.  }.  te
3860: 73 74 46 72 65 65 28 70 44 62 2d 3e 61 46 69 6c  stFree(pDb->aFil
3870: 65 5b 30 5d 2e 61 53 65 63 74 6f 72 29 3b 0a 20  e[0].aSector);. 
3880: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 44 62 2d   for(i=0; i<pDb-
3890: 3e 61 46 69 6c 65 5b 31 5d 2e 6e 53 65 63 74 6f  >aFile[1].nSecto
38a0: 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 74 65 73  r; i++){.    tes
38b0: 74 46 72 65 65 28 70 44 62 2d 3e 61 46 69 6c 65  tFree(pDb->aFile
38c0: 5b 31 5d 2e 61 53 65 63 74 6f 72 5b 69 5d 2e 61  [1].aSector[i].a
38d0: 4f 6c 64 29 3b 0a 20 20 7d 0a 20 20 74 65 73 74  Old);.  }.  test
38e0: 46 72 65 65 28 70 44 62 2d 3e 61 46 69 6c 65 5b  Free(pDb->aFile[
38f0: 31 5d 2e 61 53 65 63 74 6f 72 29 3b 0a 0a 20 20  1].aSector);..  
3900: 6d 65 6d 73 65 74 28 70 44 62 2c 20 73 69 7a 65  memset(pDb, size
3910: 6f 66 28 4c 73 6d 44 62 29 2c 20 30 78 31 31 29  of(LsmDb), 0x11)
3920: 3b 0a 20 20 74 65 73 74 46 72 65 65 28 28 63 68  ;.  testFree((ch
3930: 61 72 20 2a 29 70 44 62 2d 3e 70 42 75 66 29 3b  ar *)pDb->pBuf);
3940: 0a 20 20 74 65 73 74 46 72 65 65 28 28 63 68 61  .  testFree((cha
3950: 72 20 2a 29 70 44 62 29 3b 0a 20 20 72 65 74 75  r *)pDb);.  retu
3960: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
3970: 20 69 6e 74 20 77 61 69 74 4f 6e 43 68 65 63 6b   int waitOnCheck
3980: 70 6f 69 6e 74 65 72 28 4c 73 6d 44 62 20 2a 70  pointer(LsmDb *p
3990: 44 62 2c 20 6c 73 6d 5f 64 62 20 2a 64 62 29 7b  Db, lsm_db *db){
39a0: 0a 20 20 69 6e 74 20 6e 53 6c 65 65 70 20 3d 20  .  int nSleep = 
39b0: 30 3b 0a 20 20 69 6e 74 20 6e 4b 42 3b 0a 20 20  0;.  int nKB;.  
39c0: 69 6e 74 20 72 63 3b 0a 0a 20 20 64 6f 20 7b 0a  int rc;..  do {.
39d0: 20 20 20 20 6e 4b 42 20 3d 20 30 3b 0a 20 20 20      nKB = 0;.   
39e0: 20 72 63 20 3d 20 6c 73 6d 5f 69 6e 66 6f 28 64   rc = lsm_info(d
39f0: 62 2c 20 4c 53 4d 5f 49 4e 46 4f 5f 43 48 45 43  b, LSM_INFO_CHEC
3a00: 4b 50 4f 49 4e 54 5f 53 49 5a 45 2c 20 26 6e 4b  KPOINT_SIZE, &nK
3a10: 42 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  B);.    if( rc!=
3a20: 4c 53 4d 5f 4f 4b 20 7c 7c 20 6e 4b 42 3c 70 44  LSM_OK || nKB<pD
3a30: 62 2d 3e 6e 4d 74 4d 61 78 43 6b 70 74 20 29 20  b->nMtMaxCkpt ) 
3a40: 62 72 65 61 6b 3b 0a 20 20 20 20 75 73 6c 65 65  break;.    uslee
3a50: 70 28 35 30 30 30 29 3b 0a 20 20 20 20 6e 53 6c  p(5000);.    nSl
3a60: 65 65 70 20 2b 3d 20 35 3b 0a 20 20 7d 77 68 69  eep += 5;.  }whi
3a70: 6c 65 28 20 31 20 29 3b 0a 0a 23 69 66 20 30 0a  le( 1 );..#if 0.
3a80: 20 20 20 20 69 66 28 20 6e 53 6c 65 65 70 20 29      if( nSleep )
3a90: 20 70 72 69 6e 74 66 28 22 23 20 77 61 69 74 4f   printf("# waitO
3aa0: 6e 43 68 65 63 6b 70 6f 69 6e 74 65 72 28 29 3a  nCheckpointer():
3ab0: 20 6e 53 6c 65 65 70 3d 25 64 5c 6e 22 2c 20 6e   nSleep=%d\n", n
3ac0: 53 6c 65 65 70 29 3b 0a 23 65 6e 64 69 66 0a 0a  Sleep);.#endif..
3ad0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
3ae0: 73 74 61 74 69 63 20 69 6e 74 20 77 61 69 74 4f  static int waitO
3af0: 6e 57 6f 72 6b 65 72 28 4c 73 6d 44 62 20 2a 70  nWorker(LsmDb *p
3b00: 44 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  Db){.  int rc;. 
3b10: 20 69 6e 74 20 6e 4c 69 6d 69 74 20 3d 20 2d 31   int nLimit = -1
3b20: 3b 0a 20 20 69 6e 74 20 6e 53 6c 65 65 70 20 3d  ;.  int nSleep =
3b30: 20 30 3b 0a 0a 20 20 72 63 20 3d 20 6c 73 6d 5f   0;..  rc = lsm_
3b40: 63 6f 6e 66 69 67 28 70 44 62 2d 3e 64 62 2c 20  config(pDb->db, 
3b50: 4c 53 4d 5f 43 4f 4e 46 49 47 5f 41 55 54 4f 46  LSM_CONFIG_AUTOF
3b60: 4c 55 53 48 2c 20 26 6e 4c 69 6d 69 74 29 3b 0a  LUSH, &nLimit);.
3b70: 20 20 64 6f 20 7b 0a 20 20 20 20 69 6e 74 20 6e    do {.    int n
3b80: 4f 6c 64 2c 20 6e 4e 65 77 2c 20 72 63 3b 0a 20  Old, nNew, rc;. 
3b90: 20 20 20 72 63 20 3d 20 6c 73 6d 5f 69 6e 66 6f     rc = lsm_info
3ba0: 28 70 44 62 2d 3e 64 62 2c 20 4c 53 4d 5f 49 4e  (pDb->db, LSM_IN
3bb0: 46 4f 5f 54 52 45 45 5f 53 49 5a 45 2c 20 26 6e  FO_TREE_SIZE, &n
3bc0: 4f 6c 64 2c 20 26 6e 4e 65 77 29 3b 0a 20 20 20  Old, &nNew);.   
3bd0: 20 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20   if( rc!=LSM_OK 
3be0: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20  ) return rc;.   
3bf0: 20 69 66 28 20 6e 4f 6c 64 3d 3d 30 20 7c 7c 20   if( nOld==0 || 
3c00: 6e 4e 65 77 3c 28 6e 4c 69 6d 69 74 2f 32 29 20  nNew<(nLimit/2) 
3c10: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 75 73 6c  ) break;.    usl
3c20: 65 65 70 28 35 30 30 30 29 3b 0a 20 20 20 20 6e  eep(5000);.    n
3c30: 53 6c 65 65 70 20 2b 3d 20 35 3b 0a 20 20 7d 77  Sleep += 5;.  }w
3c40: 68 69 6c 65 28 20 31 20 29 3b 0a 0a 23 69 66 20  hile( 1 );..#if 
3c50: 30 0a 20 20 69 66 28 20 6e 53 6c 65 65 70 20 29  0.  if( nSleep )
3c60: 20 70 72 69 6e 74 66 28 22 23 20 77 61 69 74 4f   printf("# waitO
3c70: 6e 57 6f 72 6b 65 72 28 29 3a 20 6e 53 6c 65 65  nWorker(): nSlee
3c80: 70 3d 25 64 5c 6e 22 2c 20 6e 53 6c 65 65 70 29  p=%d\n", nSleep)
3c90: 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 72 65 74 75  ;.#endif..  retu
3ca0: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
3cb0: 20 69 6e 74 20 74 65 73 74 5f 6c 73 6d 5f 77 72   int test_lsm_wr
3cc0: 69 74 65 28 0a 20 20 54 65 73 74 44 62 20 2a 70  ite(.  TestDb *p
3cd0: 54 65 73 74 44 62 2c 20 0a 20 20 76 6f 69 64 20  TestDb, .  void 
3ce0: 2a 70 4b 65 79 2c 20 0a 20 20 69 6e 74 20 6e 4b  *pKey, .  int nK
3cf0: 65 79 2c 20 0a 20 20 76 6f 69 64 20 2a 70 56 61  ey, .  void *pVa
3d00: 6c 2c 0a 20 20 69 6e 74 20 6e 56 61 6c 0a 29 7b  l,.  int nVal.){
3d10: 0a 20 20 4c 73 6d 44 62 20 2a 70 44 62 20 3d 20  .  LsmDb *pDb = 
3d20: 28 4c 73 6d 44 62 20 2a 29 70 54 65 73 74 44 62  (LsmDb *)pTestDb
3d30: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d  ;.  int rc = LSM
3d40: 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 70 44 62 2d  _OK;..  if( pDb-
3d50: 3e 65 4d 6f 64 65 3d 3d 4c 53 4d 54 45 53 54 5f  >eMode==LSMTEST_
3d60: 4d 4f 44 45 5f 42 41 43 4b 47 52 4f 55 4e 44 5f  MODE_BACKGROUND_
3d70: 43 4b 50 54 20 29 7b 0a 20 20 20 20 72 63 20 3d  CKPT ){.    rc =
3d80: 20 77 61 69 74 4f 6e 43 68 65 63 6b 70 6f 69 6e   waitOnCheckpoin
3d90: 74 65 72 28 70 44 62 2c 20 70 44 62 2d 3e 64 62  ter(pDb, pDb->db
3da0: 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 0a  );.  }else if( .
3db0: 20 20 20 20 20 20 70 44 62 2d 3e 65 4d 6f 64 65        pDb->eMode
3dc0: 3d 3d 4c 53 4d 54 45 53 54 5f 4d 4f 44 45 5f 42  ==LSMTEST_MODE_B
3dd0: 41 43 4b 47 52 4f 55 4e 44 5f 57 4f 52 4b 0a 20  ACKGROUND_WORK. 
3de0: 20 20 7c 7c 20 70 44 62 2d 3e 65 4d 6f 64 65 3d    || pDb->eMode=
3df0: 3d 4c 53 4d 54 45 53 54 5f 4d 4f 44 45 5f 42 41  =LSMTEST_MODE_BA
3e00: 43 4b 47 52 4f 55 4e 44 5f 42 4f 54 48 20 0a 20  CKGROUND_BOTH . 
3e10: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 69   ){.    rc = wai
3e20: 74 4f 6e 57 6f 72 6b 65 72 28 70 44 62 29 3b 0a  tOnWorker(pDb);.
3e30: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c    }..  if( rc==L
3e40: 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  SM_OK ){.    rc 
3e50: 3d 20 6c 73 6d 5f 69 6e 73 65 72 74 28 70 44 62  = lsm_insert(pDb
3e60: 2d 3e 64 62 2c 20 70 4b 65 79 2c 20 6e 4b 65 79  ->db, pKey, nKey
3e70: 2c 20 70 56 61 6c 2c 20 6e 56 61 6c 29 3b 0a 20  , pVal, nVal);. 
3e80: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
3e90: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65  }..static int te
3ea0: 73 74 5f 6c 73 6d 5f 64 65 6c 65 74 65 28 54 65  st_lsm_delete(Te
3eb0: 73 74 44 62 20 2a 70 54 65 73 74 44 62 2c 20 76  stDb *pTestDb, v
3ec0: 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e  oid *pKey, int n
3ed0: 4b 65 79 29 7b 0a 20 20 4c 73 6d 44 62 20 2a 70  Key){.  LsmDb *p
3ee0: 44 62 20 3d 20 28 4c 73 6d 44 62 20 2a 29 70 54  Db = (LsmDb *)pT
3ef0: 65 73 74 44 62 3b 0a 20 20 72 65 74 75 72 6e 20  estDb;.  return 
3f00: 6c 73 6d 5f 64 65 6c 65 74 65 28 70 44 62 2d 3e  lsm_delete(pDb->
3f10: 64 62 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b  db, pKey, nKey);
3f20: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
3f30: 65 73 74 5f 6c 73 6d 5f 64 65 6c 65 74 65 5f 72  est_lsm_delete_r
3f40: 61 6e 67 65 28 0a 20 20 54 65 73 74 44 62 20 2a  ange(.  TestDb *
3f50: 70 54 65 73 74 44 62 2c 20 0a 20 20 76 6f 69 64  pTestDb, .  void
3f60: 20 2a 70 4b 65 79 31 2c 20 69 6e 74 20 6e 4b 65   *pKey1, int nKe
3f70: 79 31 2c 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79  y1,.  void *pKey
3f80: 32 2c 20 69 6e 74 20 6e 4b 65 79 32 0a 29 7b 0a  2, int nKey2.){.
3f90: 20 20 4c 73 6d 44 62 20 2a 70 44 62 20 3d 20 28    LsmDb *pDb = (
3fa0: 4c 73 6d 44 62 20 2a 29 70 54 65 73 74 44 62 3b  LsmDb *)pTestDb;
3fb0: 0a 20 20 72 65 74 75 72 6e 20 6c 73 6d 5f 64 65  .  return lsm_de
3fc0: 6c 65 74 65 5f 72 61 6e 67 65 28 70 44 62 2d 3e  lete_range(pDb->
3fd0: 64 62 2c 20 70 4b 65 79 31 2c 20 6e 4b 65 79 31  db, pKey1, nKey1
3fe0: 2c 20 70 4b 65 79 32 2c 20 6e 4b 65 79 32 29 3b  , pKey2, nKey2);
3ff0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
4000: 65 73 74 5f 6c 73 6d 5f 66 65 74 63 68 28 0a 20  est_lsm_fetch(. 
4010: 20 54 65 73 74 44 62 20 2a 70 54 65 73 74 44 62   TestDb *pTestDb
4020: 2c 20 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 2c  , .  void *pKey,
4030: 20 0a 20 20 69 6e 74 20 6e 4b 65 79 2c 20 0a 20   .  int nKey, . 
4040: 20 76 6f 69 64 20 2a 2a 70 70 56 61 6c 2c 20 0a   void **ppVal, .
4050: 20 20 69 6e 74 20 2a 70 6e 56 61 6c 0a 29 7b 0a    int *pnVal.){.
4060: 20 20 69 6e 74 20 72 63 3b 0a 20 20 4c 73 6d 44    int rc;.  LsmD
4070: 62 20 2a 70 44 62 20 3d 20 28 4c 73 6d 44 62 20  b *pDb = (LsmDb 
4080: 2a 29 70 54 65 73 74 44 62 3b 0a 20 20 6c 73 6d  *)pTestDb;.  lsm
4090: 5f 63 75 72 73 6f 72 20 2a 63 73 72 3b 0a 0a 20  _cursor *csr;.. 
40a0: 20 69 66 28 20 70 4b 65 79 3d 3d 30 20 29 20 72   if( pKey==0 ) r
40b0: 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 0a 20  eturn LSM_OK;.. 
40c0: 20 72 63 20 3d 20 6c 73 6d 5f 63 73 72 5f 6f 70   rc = lsm_csr_op
40d0: 65 6e 28 70 44 62 2d 3e 64 62 2c 20 26 63 73 72  en(pDb->db, &csr
40e0: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 4c 53 4d  );.  if( rc!=LSM
40f0: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
4100: 0a 0a 20 20 72 63 20 3d 20 6c 73 6d 5f 63 73 72  ..  rc = lsm_csr
4110: 5f 73 65 65 6b 28 63 73 72 2c 20 70 4b 65 79 2c  _seek(csr, pKey,
4120: 20 6e 4b 65 79 2c 20 4c 53 4d 5f 53 45 45 4b 5f   nKey, LSM_SEEK_
4130: 45 51 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 4c  EQ);.  if( rc==L
4140: 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 66 28  SM_OK ){.    if(
4150: 20 6c 73 6d 5f 63 73 72 5f 76 61 6c 69 64 28 63   lsm_csr_valid(c
4160: 73 72 29 20 29 7b 0a 20 20 20 20 20 20 63 6f 6e  sr) ){.      con
4170: 73 74 20 76 6f 69 64 20 2a 70 56 61 6c 3b 20 69  st void *pVal; i
4180: 6e 74 20 6e 56 61 6c 3b 0a 20 20 20 20 20 20 72  nt nVal;.      r
4190: 63 20 3d 20 6c 73 6d 5f 63 73 72 5f 76 61 6c 75  c = lsm_csr_valu
41a0: 65 28 63 73 72 2c 20 26 70 56 61 6c 2c 20 26 6e  e(csr, &pVal, &n
41b0: 56 61 6c 29 3b 0a 20 20 20 20 20 20 69 66 28 20  Val);.      if( 
41c0: 6e 56 61 6c 3e 70 44 62 2d 3e 6e 42 75 66 20 29  nVal>pDb->nBuf )
41d0: 7b 0a 20 20 20 20 20 20 20 20 74 65 73 74 46 72  {.        testFr
41e0: 65 65 28 70 44 62 2d 3e 70 42 75 66 29 3b 0a 20  ee(pDb->pBuf);. 
41f0: 20 20 20 20 20 20 20 70 44 62 2d 3e 70 42 75 66         pDb->pBuf
4200: 20 3d 20 74 65 73 74 4d 61 6c 6c 6f 63 28 6e 56   = testMalloc(nV
4210: 61 6c 2a 32 29 3b 0a 20 20 20 20 20 20 20 20 70  al*2);.        p
4220: 44 62 2d 3e 6e 42 75 66 20 3d 20 6e 56 61 6c 2a  Db->nBuf = nVal*
4230: 32 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  2;.      }.     
4240: 20 6d 65 6d 63 70 79 28 70 44 62 2d 3e 70 42 75   memcpy(pDb->pBu
4250: 66 2c 20 70 56 61 6c 2c 20 6e 56 61 6c 29 3b 0a  f, pVal, nVal);.
4260: 20 20 20 20 20 20 2a 70 70 56 61 6c 20 3d 20 70        *ppVal = p
4270: 44 62 2d 3e 70 42 75 66 3b 0a 20 20 20 20 20 20  Db->pBuf;.      
4280: 2a 70 6e 56 61 6c 20 3d 20 6e 56 61 6c 3b 0a 20  *pnVal = nVal;. 
4290: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
42a0: 2a 70 70 56 61 6c 20 3d 20 30 3b 0a 20 20 20 20  *ppVal = 0;.    
42b0: 20 20 2a 70 6e 56 61 6c 20 3d 20 2d 31 3b 0a 20    *pnVal = -1;. 
42c0: 20 20 20 7d 0a 20 20 7d 0a 20 20 6c 73 6d 5f 63     }.  }.  lsm_c
42d0: 73 72 5f 63 6c 6f 73 65 28 63 73 72 29 3b 0a 20  sr_close(csr);. 
42e0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
42f0: 74 61 74 69 63 20 69 6e 74 20 74 65 73 74 5f 6c  tatic int test_l
4300: 73 6d 5f 73 63 61 6e 28 0a 20 20 54 65 73 74 44  sm_scan(.  TestD
4310: 62 20 2a 70 54 65 73 74 44 62 2c 0a 20 20 76 6f  b *pTestDb,.  vo
4320: 69 64 20 2a 70 43 74 78 2c 0a 20 20 69 6e 74 20  id *pCtx,.  int 
4330: 62 52 65 76 65 72 73 65 2c 0a 20 20 76 6f 69 64  bReverse,.  void
4340: 20 2a 70 46 69 72 73 74 2c 20 69 6e 74 20 6e 46   *pFirst, int nF
4350: 69 72 73 74 2c 0a 20 20 76 6f 69 64 20 2a 70 4c  irst,.  void *pL
4360: 61 73 74 2c 20 69 6e 74 20 6e 4c 61 73 74 2c 0a  ast, int nLast,.
4370: 20 20 76 6f 69 64 20 28 2a 78 43 61 6c 6c 62 61    void (*xCallba
4380: 63 6b 29 28 76 6f 69 64 20 2a 2c 20 76 6f 69 64  ck)(void *, void
4390: 20 2a 2c 20 69 6e 74 20 2c 20 76 6f 69 64 20 2a   *, int , void *
43a0: 2c 20 69 6e 74 29 0a 29 7b 0a 20 20 4c 73 6d 44  , int).){.  LsmD
43b0: 62 20 2a 70 44 62 20 3d 20 28 4c 73 6d 44 62 20  b *pDb = (LsmDb 
43c0: 2a 29 70 54 65 73 74 44 62 3b 0a 20 20 6c 73 6d  *)pTestDb;.  lsm
43d0: 5f 63 75 72 73 6f 72 20 2a 63 73 72 3b 0a 20 20  _cursor *csr;.  
43e0: 69 6e 74 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20  int rc;..  rc = 
43f0: 6c 73 6d 5f 63 73 72 5f 6f 70 65 6e 28 70 44 62  lsm_csr_open(pDb
4400: 2d 3e 64 62 2c 20 26 63 73 72 29 3b 0a 20 20 69  ->db, &csr);.  i
4410: 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20  f( rc!=LSM_OK ) 
4420: 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 69 66  return rc;..  if
4430: 28 20 62 52 65 76 65 72 73 65 20 29 7b 0a 20 20  ( bReverse ){.  
4440: 20 20 69 66 28 20 70 4c 61 73 74 20 29 7b 0a 20    if( pLast ){. 
4450: 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 5f 63 73       rc = lsm_cs
4460: 72 5f 73 65 65 6b 28 63 73 72 2c 20 70 4c 61 73  r_seek(csr, pLas
4470: 74 2c 20 6e 4c 61 73 74 2c 20 4c 53 4d 5f 53 45  t, nLast, LSM_SE
4480: 45 4b 5f 4c 45 29 3b 0a 20 20 20 20 7d 65 6c 73  EK_LE);.    }els
4490: 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 73  e{.      rc = ls
44a0: 6d 5f 63 73 72 5f 6c 61 73 74 28 63 73 72 29 3b  m_csr_last(csr);
44b0: 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a  .    }.  }else{.
44c0: 20 20 20 20 69 66 28 20 70 46 69 72 73 74 20 29      if( pFirst )
44d0: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d  {.      rc = lsm
44e0: 5f 63 73 72 5f 73 65 65 6b 28 63 73 72 2c 20 70  _csr_seek(csr, p
44f0: 46 69 72 73 74 2c 20 6e 46 69 72 73 74 2c 20 4c  First, nFirst, L
4500: 53 4d 5f 53 45 45 4b 5f 47 45 29 3b 0a 20 20 20  SM_SEEK_GE);.   
4510: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63   }else{.      rc
4520: 20 3d 20 6c 73 6d 5f 63 73 72 5f 66 69 72 73 74   = lsm_csr_first
4530: 28 63 73 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  (csr);.    }.  }
4540: 0a 0a 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 4c  ..  while( rc==L
4550: 53 4d 5f 4f 4b 20 26 26 20 6c 73 6d 5f 63 73 72  SM_OK && lsm_csr
4560: 5f 76 61 6c 69 64 28 63 73 72 29 20 29 7b 0a 20  _valid(csr) ){. 
4570: 20 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70     const void *p
4580: 4b 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 0a 20  Key; int nKey;. 
4590: 20 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70     const void *p
45a0: 56 61 6c 3b 20 69 6e 74 20 6e 56 61 6c 3b 0a 20  Val; int nVal;. 
45b0: 20 20 20 69 6e 74 20 63 6d 70 3b 0a 0a 20 20 20     int cmp;..   
45c0: 20 6c 73 6d 5f 63 73 72 5f 6b 65 79 28 63 73 72   lsm_csr_key(csr
45d0: 2c 20 26 70 4b 65 79 2c 20 26 6e 4b 65 79 29 3b  , &pKey, &nKey);
45e0: 0a 20 20 20 20 6c 73 6d 5f 63 73 72 5f 76 61 6c  .    lsm_csr_val
45f0: 75 65 28 63 73 72 2c 20 26 70 56 61 6c 2c 20 26  ue(csr, &pVal, &
4600: 6e 56 61 6c 29 3b 0a 0a 20 20 20 20 69 66 28 20  nVal);..    if( 
4610: 62 52 65 76 65 72 73 65 20 26 26 20 70 46 69 72  bReverse && pFir
4620: 73 74 20 29 7b 0a 20 20 20 20 20 20 63 6d 70 20  st ){.      cmp 
4630: 3d 20 6d 65 6d 63 6d 70 28 70 46 69 72 73 74 2c  = memcmp(pFirst,
4640: 20 70 4b 65 79 2c 20 4d 49 4e 28 6e 4b 65 79 2c   pKey, MIN(nKey,
4650: 20 6e 46 69 72 73 74 29 29 3b 0a 20 20 20 20 20   nFirst));.     
4660: 20 69 66 28 20 63 6d 70 3e 30 20 7c 7c 20 28 63   if( cmp>0 || (c
4670: 6d 70 3d 3d 30 20 26 26 20 6e 46 69 72 73 74 3e  mp==0 && nFirst>
4680: 6e 4b 65 79 29 20 29 20 62 72 65 61 6b 3b 0a 20  nKey) ) break;. 
4690: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 62 52 65     }else if( bRe
46a0: 76 65 72 73 65 3d 3d 30 20 26 26 20 70 4c 61 73  verse==0 && pLas
46b0: 74 20 29 7b 0a 20 20 20 20 20 20 63 6d 70 20 3d  t ){.      cmp =
46c0: 20 6d 65 6d 63 6d 70 28 70 4c 61 73 74 2c 20 70   memcmp(pLast, p
46d0: 4b 65 79 2c 20 4d 49 4e 28 6e 4b 65 79 2c 20 6e  Key, MIN(nKey, n
46e0: 4c 61 73 74 29 29 3b 0a 20 20 20 20 20 20 69 66  Last));.      if
46f0: 28 20 63 6d 70 3c 30 20 7c 7c 20 28 63 6d 70 3d  ( cmp<0 || (cmp=
4700: 3d 30 20 26 26 20 6e 4c 61 73 74 3c 6e 4b 65 79  =0 && nLast<nKey
4710: 29 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d  ) ) break;.    }
4720: 0a 0a 20 20 20 20 78 43 61 6c 6c 62 61 63 6b 28  ..    xCallback(
4730: 70 43 74 78 2c 20 28 76 6f 69 64 20 2a 29 70 4b  pCtx, (void *)pK
4740: 65 79 2c 20 6e 4b 65 79 2c 20 28 76 6f 69 64 20  ey, nKey, (void 
4750: 2a 29 70 56 61 6c 2c 20 6e 56 61 6c 29 3b 0a 0a  *)pVal, nVal);..
4760: 20 20 20 20 69 66 28 20 62 52 65 76 65 72 73 65      if( bReverse
4770: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 6c   ){.      rc = l
4780: 73 6d 5f 63 73 72 5f 70 72 65 76 28 63 73 72 29  sm_csr_prev(csr)
4790: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
47a0: 20 20 20 72 63 20 3d 20 6c 73 6d 5f 63 73 72 5f     rc = lsm_csr_
47b0: 6e 65 78 74 28 63 73 72 29 3b 0a 20 20 20 20 7d  next(csr);.    }
47c0: 0a 20 20 7d 0a 0a 20 20 6c 73 6d 5f 63 73 72 5f  .  }..  lsm_csr_
47d0: 63 6c 6f 73 65 28 63 73 72 29 3b 0a 20 20 72 65  close(csr);.  re
47e0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
47f0: 69 63 20 69 6e 74 20 74 65 73 74 5f 6c 73 6d 5f  ic int test_lsm_
4800: 62 65 67 69 6e 28 54 65 73 74 44 62 20 2a 70 54  begin(TestDb *pT
4810: 65 73 74 44 62 2c 20 69 6e 74 20 69 4c 65 76 65  estDb, int iLeve
4820: 6c 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c  l){.  int rc = L
4830: 53 4d 5f 4f 4b 3b 0a 20 20 4c 73 6d 44 62 20 2a  SM_OK;.  LsmDb *
4840: 70 44 62 20 3d 20 28 4c 73 6d 44 62 20 2a 29 70  pDb = (LsmDb *)p
4850: 54 65 73 74 44 62 3b 0a 0a 20 20 2f 2a 20 69 4c  TestDb;..  /* iL
4860: 65 76 65 6c 3d 3d 30 20 69 73 20 61 20 6e 6f 2d  evel==0 is a no-
4870: 6f 70 2e 20 2a 2f 0a 20 20 69 66 28 20 69 4c 65  op. */.  if( iLe
4880: 76 65 6c 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  vel==0 ) return 
4890: 30 3b 0a 0a 20 20 69 66 28 20 70 44 62 2d 3e 70  0;..  if( pDb->p
48a0: 43 73 72 3d 3d 30 20 29 20 72 63 20 3d 20 6c 73  Csr==0 ) rc = ls
48b0: 6d 5f 63 73 72 5f 6f 70 65 6e 28 70 44 62 2d 3e  m_csr_open(pDb->
48c0: 64 62 2c 20 26 70 44 62 2d 3e 70 43 73 72 29 3b  db, &pDb->pCsr);
48d0: 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f  .  if( rc==LSM_O
48e0: 4b 20 26 26 20 69 4c 65 76 65 6c 3e 31 20 29 7b  K && iLevel>1 ){
48f0: 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 5f 62 65  .    rc = lsm_be
4900: 67 69 6e 28 70 44 62 2d 3e 64 62 2c 20 69 4c 65  gin(pDb->db, iLe
4910: 76 65 6c 2d 31 29 3b 0a 20 20 7d 0a 0a 20 20 72  vel-1);.  }..  r
4920: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74  eturn rc;.}.stat
4930: 69 63 20 69 6e 74 20 74 65 73 74 5f 6c 73 6d 5f  ic int test_lsm_
4940: 63 6f 6d 6d 69 74 28 54 65 73 74 44 62 20 2a 70  commit(TestDb *p
4950: 54 65 73 74 44 62 2c 20 69 6e 74 20 69 4c 65 76  TestDb, int iLev
4960: 65 6c 29 7b 0a 20 20 4c 73 6d 44 62 20 2a 70 44  el){.  LsmDb *pD
4970: 62 20 3d 20 28 4c 73 6d 44 62 20 2a 29 70 54 65  b = (LsmDb *)pTe
4980: 73 74 44 62 3b 0a 0a 20 20 2f 2a 20 49 66 20 69  stDb;..  /* If i
4990: 4c 65 76 65 6c 3d 3d 30 2c 20 63 6c 6f 73 65 20  Level==0, close 
49a0: 61 6e 79 20 6f 70 65 6e 20 72 65 61 64 20 74 72  any open read tr
49b0: 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 69  ansaction */.  i
49c0: 66 28 20 69 4c 65 76 65 6c 3d 3d 30 20 26 26 20  f( iLevel==0 && 
49d0: 70 44 62 2d 3e 70 43 73 72 20 29 7b 0a 20 20 20  pDb->pCsr ){.   
49e0: 20 6c 73 6d 5f 63 73 72 5f 63 6c 6f 73 65 28 70   lsm_csr_close(p
49f0: 44 62 2d 3e 70 43 73 72 29 3b 0a 20 20 20 20 70  Db->pCsr);.    p
4a00: 44 62 2d 3e 70 43 73 72 20 3d 20 30 3b 0a 20 20  Db->pCsr = 0;.  
4a10: 7d 0a 0a 20 20 2f 2a 20 49 66 20 69 4c 65 76 65  }..  /* If iLeve
4a20: 6c 3d 3d 30 2c 20 63 6c 6f 73 65 20 61 6e 79 20  l==0, close any 
4a30: 6f 70 65 6e 20 72 65 61 64 20 74 72 61 6e 73 61  open read transa
4a40: 63 74 69 6f 6e 20 2a 2f 0a 20 20 72 65 74 75 72  ction */.  retur
4a50: 6e 20 6c 73 6d 5f 63 6f 6d 6d 69 74 28 70 44 62  n lsm_commit(pDb
4a60: 2d 3e 64 62 2c 20 4d 41 58 28 30 2c 20 69 4c 65  ->db, MAX(0, iLe
4a70: 76 65 6c 2d 31 29 29 3b 0a 7d 0a 73 74 61 74 69  vel-1));.}.stati
4a80: 63 20 69 6e 74 20 74 65 73 74 5f 6c 73 6d 5f 72  c int test_lsm_r
4a90: 6f 6c 6c 62 61 63 6b 28 54 65 73 74 44 62 20 2a  ollback(TestDb *
4aa0: 70 54 65 73 74 44 62 2c 20 69 6e 74 20 69 4c 65  pTestDb, int iLe
4ab0: 76 65 6c 29 7b 0a 20 20 4c 73 6d 44 62 20 2a 70  vel){.  LsmDb *p
4ac0: 44 62 20 3d 20 28 4c 73 6d 44 62 20 2a 29 70 54  Db = (LsmDb *)pT
4ad0: 65 73 74 44 62 3b 0a 0a 20 20 2f 2a 20 49 66 20  estDb;..  /* If 
4ae0: 69 4c 65 76 65 6c 3d 3d 30 2c 20 63 6c 6f 73 65  iLevel==0, close
4af0: 20 61 6e 79 20 6f 70 65 6e 20 72 65 61 64 20 74   any open read t
4b00: 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20  ransaction */.  
4b10: 69 66 28 20 69 4c 65 76 65 6c 3d 3d 30 20 26 26  if( iLevel==0 &&
4b20: 20 70 44 62 2d 3e 70 43 73 72 20 29 7b 0a 20 20   pDb->pCsr ){.  
4b30: 20 20 6c 73 6d 5f 63 73 72 5f 63 6c 6f 73 65 28    lsm_csr_close(
4b40: 70 44 62 2d 3e 70 43 73 72 29 3b 0a 20 20 20 20  pDb->pCsr);.    
4b50: 70 44 62 2d 3e 70 43 73 72 20 3d 20 30 3b 0a 20  pDb->pCsr = 0;. 
4b60: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 6c 73 6d   }..  return lsm
4b70: 5f 72 6f 6c 6c 62 61 63 6b 28 70 44 62 2d 3e 64  _rollback(pDb->d
4b80: 62 2c 20 4d 41 58 28 30 2c 20 69 4c 65 76 65 6c  b, MAX(0, iLevel
4b90: 2d 31 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  -1));.}../*.** A
4ba0: 20 6c 6f 67 20 6d 65 73 73 61 67 65 20 63 61 6c   log message cal
4bb0: 6c 62 61 63 6b 20 72 65 67 69 73 74 65 72 65 64  lback registered
4bc0: 20 77 69 74 68 20 6c 73 6d 20 63 6f 6e 6e 65 63   with lsm connec
4bd0: 74 69 6f 6e 73 2e 20 50 72 69 6e 74 73 20 61 6c  tions. Prints al
4be0: 6c 20 0a 2a 2a 20 6d 65 73 73 61 67 65 73 20 74  l .** messages t
4bf0: 6f 20 73 74 64 65 72 72 2e 0a 2a 2f 0a 73 74 61  o stderr..*/.sta
4c00: 74 69 63 20 76 6f 69 64 20 78 4c 6f 67 28 76 6f  tic void xLog(vo
4c10: 69 64 20 2a 70 43 74 78 2c 20 69 6e 74 20 72 63  id *pCtx, int rc
4c20: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 29  , const char *z)
4c30: 7b 0a 20 20 75 6e 75 73 65 64 5f 70 61 72 61 6d  {.  unused_param
4c40: 65 74 65 72 28 72 63 29 3b 0a 20 20 2f 2a 20 66  eter(rc);.  /* f
4c50: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
4c60: 6c 73 6d 3a 20 72 63 3d 25 64 20 5c 22 25 73 5c  lsm: rc=%d \"%s\
4c70: 22 5c 6e 22 2c 20 72 63 2c 20 7a 29 3b 20 2a 2f  "\n", rc, z); */
4c80: 0a 20 20 69 66 28 20 70 43 74 78 20 29 20 66 70  .  if( pCtx ) fp
4c90: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25  rintf(stderr, "%
4ca0: 73 3a 20 22 2c 20 28 63 68 61 72 20 2a 29 70 43  s: ", (char *)pC
4cb0: 74 78 29 3b 0a 20 20 66 70 72 69 6e 74 66 28 73  tx);.  fprintf(s
4cc0: 74 64 65 72 72 2c 20 22 25 73 5c 6e 22 2c 20 7a  tderr, "%s\n", z
4cd0: 29 3b 0a 20 20 66 66 6c 75 73 68 28 73 74 64 65  );.  fflush(stde
4ce0: 72 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  rr);.}..static v
4cf0: 6f 69 64 20 78 57 6f 72 6b 48 6f 6f 6b 28 6c 73  oid xWorkHook(ls
4d00: 6d 5f 64 62 20 2a 64 62 2c 20 76 6f 69 64 20 2a  m_db *db, void *
4d10: 70 41 72 67 29 7b 0a 20 20 4c 73 6d 44 62 20 2a  pArg){.  LsmDb *
4d20: 70 20 3d 20 28 4c 73 6d 44 62 20 2a 29 70 41 72  p = (LsmDb *)pAr
4d30: 67 3b 0a 20 20 69 66 28 20 70 2d 3e 78 57 6f 72  g;.  if( p->xWor
4d40: 6b 20 29 20 70 2d 3e 78 57 6f 72 6b 28 64 62 2c  k ) p->xWork(db,
4d50: 20 70 2d 3e 70 57 6f 72 6b 43 74 78 29 3b 0a 7d   p->pWorkCtx);.}
4d60: 0a 0a 23 64 65 66 69 6e 65 20 54 45 53 54 5f 4e  ..#define TEST_N
4d70: 4f 5f 52 45 43 4f 56 45 52 59 20 2d 31 0a 23 64  O_RECOVERY -1.#d
4d80: 65 66 69 6e 65 20 54 45 53 54 5f 43 4f 4d 50 52  efine TEST_COMPR
4d90: 45 53 53 49 4f 4e 20 2d 33 0a 0a 23 64 65 66 69  ESSION -3..#defi
4da0: 6e 65 20 54 45 53 54 5f 4d 54 5f 4d 4f 44 45 20  ne TEST_MT_MODE 
4db0: 20 20 20 20 2d 32 0a 23 64 65 66 69 6e 65 20 54      -2.#define T
4dc0: 45 53 54 5f 4d 54 5f 4d 49 4e 5f 43 4b 50 54 20  EST_MT_MIN_CKPT 
4dd0: 2d 34 0a 23 64 65 66 69 6e 65 20 54 45 53 54 5f  -4.#define TEST_
4de0: 4d 54 5f 4d 41 58 5f 43 4b 50 54 20 2d 35 0a 0a  MT_MAX_CKPT -5..
4df0: 69 6e 74 20 74 65 73 74 5f 6c 73 6d 5f 63 6f 6e  int test_lsm_con
4e00: 66 69 67 5f 73 74 72 28 0a 20 20 4c 73 6d 44 62  fig_str(.  LsmDb
4e10: 20 2a 70 4c 73 6d 2c 0a 20 20 6c 73 6d 5f 64 62   *pLsm,.  lsm_db
4e20: 20 2a 64 62 2c 20 0a 20 20 69 6e 74 20 62 57 6f   *db, .  int bWo
4e30: 72 6b 65 72 2c 0a 20 20 63 6f 6e 73 74 20 63 68  rker,.  const ch
4e40: 61 72 20 2a 7a 53 74 72 2c 0a 20 20 69 6e 74 20  ar *zStr,.  int 
4e50: 2a 70 6e 54 68 72 65 61 64 0a 29 7b 0a 20 20 73  *pnThread.){.  s
4e60: 74 72 75 63 74 20 43 66 67 50 61 72 61 6d 20 7b  truct CfgParam {
4e70: 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20  .    const char 
4e80: 2a 7a 50 61 72 61 6d 3b 0a 20 20 20 20 69 6e 74  *zParam;.    int
4e90: 20 62 57 6f 72 6b 65 72 3b 0a 20 20 20 20 69 6e   bWorker;.    in
4ea0: 74 20 65 50 61 72 61 6d 3b 0a 20 20 7d 20 61 50  t eParam;.  } aP
4eb0: 61 72 61 6d 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b  aram[] = {.    {
4ec0: 20 22 61 75 74 6f 66 6c 75 73 68 22 2c 20 20 20   "autoflush",   
4ed0: 20 20 20 20 20 30 2c 20 4c 53 4d 5f 43 4f 4e 46       0, LSM_CONF
4ee0: 49 47 5f 41 55 54 4f 46 4c 55 53 48 20 7d 2c 0a  IG_AUTOFLUSH },.
4ef0: 20 20 20 20 7b 20 22 70 61 67 65 5f 73 69 7a 65      { "page_size
4f00: 22 2c 20 20 20 20 20 20 20 20 30 2c 20 4c 53 4d  ",        0, LSM
4f10: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 5f 53 49 5a  _CONFIG_PAGE_SIZ
4f20: 45 20 7d 2c 0a 20 20 20 20 7b 20 22 62 6c 6f 63  E },.    { "bloc
4f30: 6b 5f 73 69 7a 65 22 2c 20 20 20 20 20 20 20 30  k_size",       0
4f40: 2c 20 4c 53 4d 5f 43 4f 4e 46 49 47 5f 42 4c 4f  , LSM_CONFIG_BLO
4f50: 43 4b 5f 53 49 5a 45 20 7d 2c 0a 20 20 20 20 7b  CK_SIZE },.    {
4f60: 20 22 73 61 66 65 74 79 22 2c 20 20 20 20 20 20   "safety",      
4f70: 20 20 20 20 20 30 2c 20 4c 53 4d 5f 43 4f 4e 46       0, LSM_CONF
4f80: 49 47 5f 53 41 46 45 54 59 20 7d 2c 0a 20 20 20  IG_SAFETY },.   
4f90: 20 7b 20 22 61 75 74 6f 77 6f 72 6b 22 2c 20 20   { "autowork",  
4fa0: 20 20 20 20 20 20 20 30 2c 20 4c 53 4d 5f 43 4f         0, LSM_CO
4fb0: 4e 46 49 47 5f 41 55 54 4f 57 4f 52 4b 20 7d 2c  NFIG_AUTOWORK },
4fc0: 0a 20 20 20 20 7b 20 22 61 75 74 6f 63 68 65 63  .    { "autochec
4fd0: 6b 70 6f 69 6e 74 22 2c 20 20 20 30 2c 20 4c 53  kpoint",   0, LS
4fe0: 4d 5f 43 4f 4e 46 49 47 5f 41 55 54 4f 43 48 45  M_CONFIG_AUTOCHE
4ff0: 43 4b 50 4f 49 4e 54 20 7d 2c 0a 20 20 20 20 7b  CKPOINT },.    {
5000: 20 22 6d 6d 61 70 22 2c 20 20 20 20 20 20 20 20   "mmap",        
5010: 20 20 20 20 20 30 2c 20 4c 53 4d 5f 43 4f 4e 46       0, LSM_CONF
5020: 49 47 5f 4d 4d 41 50 20 7d 2c 0a 20 20 20 20 7b  IG_MMAP },.    {
5030: 20 22 75 73 65 5f 6c 6f 67 22 2c 20 20 20 20 20   "use_log",     
5040: 20 20 20 20 20 30 2c 20 4c 53 4d 5f 43 4f 4e 46       0, LSM_CONF
5050: 49 47 5f 55 53 45 5f 4c 4f 47 20 7d 2c 0a 20 20  IG_USE_LOG },.  
5060: 20 20 7b 20 22 61 75 74 6f 6d 65 72 67 65 22 2c    { "automerge",
5070: 20 20 20 20 20 20 20 20 30 2c 20 4c 53 4d 5f 43          0, LSM_C
5080: 4f 4e 46 49 47 5f 41 55 54 4f 4d 45 52 47 45 20  ONFIG_AUTOMERGE 
5090: 7d 2c 0a 20 20 20 20 7b 20 22 6d 61 78 5f 66 72  },.    { "max_fr
50a0: 65 65 6c 69 73 74 22 2c 20 20 20 20 20 30 2c 20  eelist",     0, 
50b0: 4c 53 4d 5f 43 4f 4e 46 49 47 5f 4d 41 58 5f 46  LSM_CONFIG_MAX_F
50c0: 52 45 45 4c 49 53 54 20 7d 2c 0a 20 20 20 20 7b  REELIST },.    {
50d0: 20 22 6d 75 6c 74 69 5f 70 72 6f 63 22 2c 20 20   "multi_proc",  
50e0: 20 20 20 20 20 30 2c 20 4c 53 4d 5f 43 4f 4e 46       0, LSM_CONF
50f0: 49 47 5f 4d 55 4c 54 49 50 4c 45 5f 50 52 4f 43  IG_MULTIPLE_PROC
5100: 45 53 53 45 53 20 7d 2c 0a 20 20 20 20 7b 20 22  ESSES },.    { "
5110: 77 6f 72 6b 65 72 5f 61 75 74 6f 6d 65 72 67 65  worker_automerge
5120: 22 2c 20 31 2c 20 4c 53 4d 5f 43 4f 4e 46 49 47  ", 1, LSM_CONFIG
5130: 5f 41 55 54 4f 4d 45 52 47 45 20 7d 2c 0a 20 20  _AUTOMERGE },.  
5140: 20 20 7b 20 22 74 65 73 74 5f 6e 6f 5f 72 65 63    { "test_no_rec
5150: 6f 76 65 72 79 22 2c 20 30 2c 20 54 45 53 54 5f  overy", 0, TEST_
5160: 4e 4f 5f 52 45 43 4f 56 45 52 59 20 7d 2c 0a 20  NO_RECOVERY },. 
5170: 20 20 20 7b 20 22 62 67 5f 6d 69 6e 5f 63 6b 70     { "bg_min_ckp
5180: 74 22 2c 20 20 20 20 20 20 30 2c 20 54 45 53 54  t",      0, TEST
5190: 5f 4e 4f 5f 52 45 43 4f 56 45 52 59 20 7d 2c 0a  _NO_RECOVERY },.
51a0: 0a 20 20 20 20 7b 20 22 6d 74 5f 6d 6f 64 65 22  .    { "mt_mode"
51b0: 2c 20 20 20 20 20 20 20 20 20 20 30 2c 20 54 45  ,          0, TE
51c0: 53 54 5f 4d 54 5f 4d 4f 44 45 20 7d 2c 0a 20 20  ST_MT_MODE },.  
51d0: 20 20 7b 20 22 6d 74 5f 6d 69 6e 5f 63 6b 70 74    { "mt_min_ckpt
51e0: 22 2c 20 20 20 20 20 20 30 2c 20 54 45 53 54 5f  ",      0, TEST_
51f0: 4d 54 5f 4d 49 4e 5f 43 4b 50 54 20 7d 2c 0a 20  MT_MIN_CKPT },. 
5200: 20 20 20 7b 20 22 6d 74 5f 6d 61 78 5f 63 6b 70     { "mt_max_ckp
5210: 74 22 2c 20 20 20 20 20 20 30 2c 20 54 45 53 54  t",      0, TEST
5220: 5f 4d 54 5f 4d 41 58 5f 43 4b 50 54 20 7d 2c 0a  _MT_MAX_CKPT },.
5230: 0a 23 69 66 64 65 66 20 48 41 56 45 5f 5a 4c 49  .#ifdef HAVE_ZLI
5240: 42 0a 20 20 20 20 7b 20 22 63 6f 6d 70 72 65 73  B.    { "compres
5250: 73 69 6f 6e 22 2c 20 20 20 20 20 20 30 2c 20 54  sion",      0, T
5260: 45 53 54 5f 43 4f 4d 50 52 45 53 53 49 4f 4e 20  EST_COMPRESSION 
5270: 7d 2c 0a 23 65 6e 64 69 66 0a 20 20 20 20 7b 20  },.#endif.    { 
5280: 30 2c 20 30 20 7d 0a 20 20 7d 3b 0a 20 20 63 6f  0, 0 }.  };.  co
5290: 6e 73 74 20 63 68 61 72 20 2a 7a 20 3d 20 7a 53  nst char *z = zS
52a0: 74 72 3b 0a 20 20 69 6e 74 20 6e 54 68 72 65 61  tr;.  int nThrea
52b0: 64 20 3d 20 31 3b 0a 0a 20 20 61 73 73 65 72 74  d = 1;..  assert
52c0: 28 20 64 62 20 29 3b 0a 20 20 77 68 69 6c 65 28  ( db );.  while(
52d0: 20 7a 5b 30 5d 20 29 7b 0a 20 20 20 20 63 6f 6e   z[0] ){.    con
52e0: 73 74 20 63 68 61 72 20 2a 7a 53 74 61 72 74 3b  st char *zStart;
52f0: 0a 0a 20 20 20 20 2f 2a 20 53 6b 69 70 20 77 68  ..    /* Skip wh
5300: 69 74 65 73 70 61 63 65 20 2a 2f 0a 20 20 20 20  itespace */.    
5310: 77 68 69 6c 65 28 20 2a 7a 3d 3d 27 20 27 20 29  while( *z==' ' )
5320: 20 7a 2b 2b 3b 0a 20 20 20 20 7a 53 74 61 72 74   z++;.    zStart
5330: 20 3d 20 7a 3b 0a 0a 20 20 20 20 77 68 69 6c 65   = z;..    while
5340: 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 3d 27 20  ( *z && *z!='=' 
5350: 29 20 7a 2b 2b 3b 0a 20 20 20 20 69 66 28 20 2a  ) z++;.    if( *
5360: 7a 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 65  z ){.      int e
5370: 50 61 72 61 6d 3b 0a 20 20 20 20 20 20 69 6e 74  Param;.      int
5380: 20 69 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 56   i;.      int iV
5390: 61 6c 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 4d  al;.      int iM
53a0: 75 6c 20 3d 20 31 3b 0a 20 20 20 20 20 20 69 6e  ul = 1;.      in
53b0: 74 20 72 63 3b 0a 20 20 20 20 20 20 63 68 61 72  t rc;.      char
53c0: 20 7a 50 61 72 61 6d 5b 33 32 5d 3b 0a 20 20 20   zParam[32];.   
53d0: 20 20 20 69 6e 74 20 6e 50 61 72 61 6d 20 3d 20     int nParam = 
53e0: 7a 2d 7a 53 74 61 72 74 3b 0a 20 20 20 20 20 20  z-zStart;.      
53f0: 69 66 28 20 6e 50 61 72 61 6d 3d 3d 30 20 7c 7c  if( nParam==0 ||
5400: 20 6e 50 61 72 61 6d 3e 73 69 7a 65 6f 66 28 7a   nParam>sizeof(z
5410: 50 61 72 61 6d 29 2d 31 20 29 20 67 6f 74 6f 20  Param)-1 ) goto 
5420: 73 79 6e 74 61 78 5f 65 72 72 6f 72 3b 0a 0a 20  syntax_error;.. 
5430: 20 20 20 20 20 6d 65 6d 63 70 79 28 7a 50 61 72       memcpy(zPar
5440: 61 6d 2c 20 7a 53 74 61 72 74 2c 20 6e 50 61 72  am, zStart, nPar
5450: 61 6d 29 3b 0a 20 20 20 20 20 20 7a 50 61 72 61  am);.      zPara
5460: 6d 5b 6e 50 61 72 61 6d 5d 20 3d 20 27 5c 30 27  m[nParam] = '\0'
5470: 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 74 65 73  ;.      rc = tes
5480: 74 41 72 67 53 65 6c 65 63 74 28 61 50 61 72 61  tArgSelect(aPara
5490: 6d 2c 20 22 70 61 72 61 6d 22 2c 20 7a 50 61 72  m, "param", zPar
54a0: 61 6d 2c 20 26 69 29 3b 0a 20 20 20 20 20 20 69  am, &i);.      i
54b0: 66 28 20 72 63 21 3d 30 20 29 20 72 65 74 75 72  f( rc!=0 ) retur
54c0: 6e 20 72 63 3b 0a 20 20 20 20 20 20 65 50 61 72  n rc;.      ePar
54d0: 61 6d 20 3d 20 61 50 61 72 61 6d 5b 69 5d 2e 65  am = aParam[i].e
54e0: 50 61 72 61 6d 3b 0a 0a 20 20 20 20 20 20 7a 2b  Param;..      z+
54f0: 2b 3b 0a 20 20 20 20 20 20 7a 53 74 61 72 74 20  +;.      zStart 
5500: 3d 20 7a 3b 0a 20 20 20 20 20 20 77 68 69 6c 65  = z;.      while
5510: 28 20 2a 7a 3e 3d 27 30 27 20 26 26 20 2a 7a 3c  ( *z>='0' && *z<
5520: 3d 27 39 27 20 29 20 7a 2b 2b 3b 0a 20 20 20 20  ='9' ) z++;.    
5530: 20 20 69 66 28 20 2a 7a 3d 3d 27 6b 27 20 7c 7c    if( *z=='k' ||
5540: 20 2a 7a 3d 3d 27 4b 27 20 29 7b 0a 20 20 20 20   *z=='K' ){.    
5550: 20 20 20 20 69 4d 75 6c 20 3d 20 31 3b 0a 20 20      iMul = 1;.  
5560: 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20        z++;.     
5570: 20 7d 65 6c 73 65 20 69 66 28 20 2a 7a 3d 3d 27   }else if( *z=='
5580: 4d 27 20 7c 7c 20 2a 7a 3d 3d 27 4d 27 20 29 7b  M' || *z=='M' ){
5590: 0a 20 20 20 20 20 20 20 20 69 4d 75 6c 20 3d 20  .        iMul = 
55a0: 31 30 32 34 3b 0a 20 20 20 20 20 20 20 20 7a 2b  1024;.        z+
55b0: 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  +;.      }.     
55c0: 20 6e 50 61 72 61 6d 20 3d 20 7a 2d 7a 53 74 61   nParam = z-zSta
55d0: 72 74 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 50  rt;.      if( nP
55e0: 61 72 61 6d 3d 3d 30 20 7c 7c 20 6e 50 61 72 61  aram==0 || nPara
55f0: 6d 3e 73 69 7a 65 6f 66 28 7a 50 61 72 61 6d 29  m>sizeof(zParam)
5600: 2d 31 20 29 20 67 6f 74 6f 20 73 79 6e 74 61 78  -1 ) goto syntax
5610: 5f 65 72 72 6f 72 3b 0a 20 20 20 20 20 20 6d 65  _error;.      me
5620: 6d 63 70 79 28 7a 50 61 72 61 6d 2c 20 7a 53 74  mcpy(zParam, zSt
5630: 61 72 74 2c 20 6e 50 61 72 61 6d 29 3b 0a 20 20  art, nParam);.  
5640: 20 20 20 20 7a 50 61 72 61 6d 5b 6e 50 61 72 61      zParam[nPara
5650: 6d 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 20 20 20  m] = '\0';.     
5660: 20 69 56 61 6c 20 3d 20 61 74 6f 69 28 7a 50 61   iVal = atoi(zPa
5670: 72 61 6d 29 20 2a 20 69 4d 75 6c 3b 0a 0a 20 20  ram) * iMul;..  
5680: 20 20 20 20 69 66 28 20 65 50 61 72 61 6d 3e 30      if( eParam>0
5690: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
56a0: 62 57 6f 72 6b 65 72 20 7c 7c 20 61 50 61 72 61  bWorker || aPara
56b0: 6d 5b 69 5d 2e 62 57 6f 72 6b 65 72 3d 3d 30 20  m[i].bWorker==0 
56c0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6c 73 6d  ){.          lsm
56d0: 5f 63 6f 6e 66 69 67 28 64 62 2c 20 65 50 61 72  _config(db, ePar
56e0: 61 6d 2c 20 26 69 56 61 6c 29 3b 0a 20 20 20 20  am, &iVal);.    
56f0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73      }.      }els
5700: 65 7b 0a 20 20 20 20 20 20 20 20 73 77 69 74 63  e{.        switc
5710: 68 28 20 65 50 61 72 61 6d 20 29 7b 0a 20 20 20  h( eParam ){.   
5720: 20 20 20 20 20 20 20 63 61 73 65 20 54 45 53 54         case TEST
5730: 5f 4e 4f 5f 52 45 43 4f 56 45 52 59 3a 0a 20 20  _NO_RECOVERY:.  
5740: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 70 4c            if( pL
5750: 73 6d 20 29 20 70 4c 73 6d 2d 3e 62 4e 6f 52 65  sm ) pLsm->bNoRe
5760: 63 6f 76 65 72 79 20 3d 20 69 56 61 6c 3b 0a 20  covery = iVal;. 
5770: 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b             break
5780: 3b 0a 20 20 20 20 20 20 20 20 20 20 63 61 73 65  ;.          case
5790: 20 54 45 53 54 5f 4d 54 5f 4d 4f 44 45 3a 0a 20   TEST_MT_MODE:. 
57a0: 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20 70             if( p
57b0: 4c 73 6d 20 29 20 6e 54 68 72 65 61 64 20 3d 20  Lsm ) nThread = 
57c0: 69 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 20 20  iVal;.          
57d0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20    break;.       
57e0: 20 20 20 63 61 73 65 20 54 45 53 54 5f 4d 54 5f     case TEST_MT_
57f0: 4d 49 4e 5f 43 4b 50 54 3a 0a 20 20 20 20 20 20  MIN_CKPT:.      
5800: 20 20 20 20 20 20 69 66 28 20 70 4c 73 6d 20 26        if( pLsm &
5810: 26 20 69 56 61 6c 3e 30 20 29 20 70 4c 73 6d 2d  & iVal>0 ) pLsm-
5820: 3e 6e 4d 74 4d 69 6e 43 6b 70 74 20 3d 20 69 56  >nMtMinCkpt = iV
5830: 61 6c 2a 31 30 32 34 3b 0a 20 20 20 20 20 20 20  al*1024;.       
5840: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
5850: 20 20 20 20 20 20 63 61 73 65 20 54 45 53 54 5f        case TEST_
5860: 4d 54 5f 4d 41 58 5f 43 4b 50 54 3a 0a 20 20 20  MT_MAX_CKPT:.   
5870: 20 20 20 20 20 20 20 20 20 69 66 28 20 70 4c 73           if( pLs
5880: 6d 20 26 26 20 69 56 61 6c 3e 30 20 29 20 70 4c  m && iVal>0 ) pL
5890: 73 6d 2d 3e 6e 4d 74 4d 61 78 43 6b 70 74 20 3d  sm->nMtMaxCkpt =
58a0: 20 69 56 61 6c 2a 31 30 32 34 3b 0a 20 20 20 20   iVal*1024;.    
58b0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 23          break;.#
58c0: 69 66 64 65 66 20 48 41 56 45 5f 5a 4c 49 42 0a  ifdef HAVE_ZLIB.
58d0: 20 20 20 20 20 20 20 20 20 20 63 61 73 65 20 54            case T
58e0: 45 53 54 5f 43 4f 4d 50 52 45 53 53 49 4f 4e 3a  EST_COMPRESSION:
58f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 74 65 73  .            tes
5900: 74 43 6f 6e 66 69 67 75 72 65 43 6f 6d 70 72 65  tConfigureCompre
5910: 73 73 69 6f 6e 28 64 62 29 3b 0a 20 20 20 20 20  ssion(db);.     
5920: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 23 65         break;.#e
5930: 6e 64 69 66 0a 20 20 20 20 20 20 20 20 7d 0a 20  ndif.        }. 
5940: 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65       }.    }else
5950: 20 69 66 28 20 7a 21 3d 7a 53 74 61 72 74 20 29   if( z!=zStart )
5960: 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 73 79 6e  {.      goto syn
5970: 74 61 78 5f 65 72 72 6f 72 3b 0a 20 20 20 20 7d  tax_error;.    }
5980: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 6e 54 68  .  }..  if( pnTh
5990: 72 65 61 64 20 29 20 2a 70 6e 54 68 72 65 61 64  read ) *pnThread
59a0: 20 3d 20 6e 54 68 72 65 61 64 3b 0a 20 20 69 66   = nThread;.  if
59b0: 28 20 70 4c 73 6d 20 26 26 20 70 4c 73 6d 2d 3e  ( pLsm && pLsm->
59c0: 6e 4d 74 4d 61 78 43 6b 70 74 20 3c 20 70 4c 73  nMtMaxCkpt < pLs
59d0: 6d 2d 3e 6e 4d 74 4d 69 6e 43 6b 70 74 20 29 7b  m->nMtMinCkpt ){
59e0: 0a 20 20 20 20 70 4c 73 6d 2d 3e 6e 4d 74 4d 69  .    pLsm->nMtMi
59f0: 6e 43 6b 70 74 20 3d 20 70 4c 73 6d 2d 3e 6e 4d  nCkpt = pLsm->nM
5a00: 74 4d 61 78 43 6b 70 74 3b 0a 20 20 7d 0a 0a 20  tMaxCkpt;.  }.. 
5a10: 20 72 65 74 75 72 6e 20 30 3b 0a 20 73 79 6e 74   return 0;. synt
5a20: 61 78 5f 65 72 72 6f 72 3a 0a 20 20 74 65 73 74  ax_error:.  test
5a30: 50 72 69 6e 74 45 72 72 6f 72 28 22 73 79 6e 74  PrintError("synt
5a40: 61 78 20 65 72 72 6f 72 20 61 74 3a 20 5c 22 25  ax error at: \"%
5a50: 73 5c 22 5c 6e 22 2c 20 7a 29 3b 0a 20 20 72 65  s\"\n", z);.  re
5a60: 74 75 72 6e 20 31 3b 0a 7d 0a 0a 69 6e 74 20 74  turn 1;.}..int t
5a70: 64 62 5f 6c 73 6d 5f 63 6f 6e 66 69 67 5f 73 74  db_lsm_config_st
5a80: 72 28 54 65 73 74 44 62 20 2a 70 44 62 2c 20 63  r(TestDb *pDb, c
5a90: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 72 29  onst char *zStr)
5aa0: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 30 3b 0a  {.  int rc = 0;.
5ab0: 20 20 69 66 28 20 74 64 62 5f 6c 73 6d 28 70 44    if( tdb_lsm(pD
5ac0: 62 29 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b  b) ){.    int i;
5ad0: 0a 20 20 20 20 4c 73 6d 44 62 20 2a 70 4c 73 6d  .    LsmDb *pLsm
5ae0: 20 3d 20 28 4c 73 6d 44 62 20 2a 29 70 44 62 3b   = (LsmDb *)pDb;
5af0: 0a 0a 20 20 20 20 72 63 20 3d 20 74 65 73 74 5f  ..    rc = test_
5b00: 6c 73 6d 5f 63 6f 6e 66 69 67 5f 73 74 72 28 70  lsm_config_str(p
5b10: 4c 73 6d 2c 20 70 4c 73 6d 2d 3e 64 62 2c 20 30  Lsm, pLsm->db, 0
5b20: 2c 20 7a 53 74 72 2c 20 30 29 3b 0a 23 69 66 64  , zStr, 0);.#ifd
5b30: 65 66 20 4c 53 4d 5f 4d 55 54 45 58 5f 50 54 48  ef LSM_MUTEX_PTH
5b40: 52 45 41 44 53 0a 20 20 20 20 66 6f 72 28 69 3d  READS.    for(i=
5b50: 30 3b 20 72 63 3d 3d 30 20 26 26 20 69 3c 70 4c  0; rc==0 && i<pL
5b60: 73 6d 2d 3e 6e 57 6f 72 6b 65 72 3b 20 69 2b 2b  sm->nWorker; i++
5b70: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 74 65  ){.      rc = te
5b80: 73 74 5f 6c 73 6d 5f 63 6f 6e 66 69 67 5f 73 74  st_lsm_config_st
5b90: 72 28 30 2c 20 70 4c 73 6d 2d 3e 61 57 6f 72 6b  r(0, pLsm->aWork
5ba0: 65 72 5b 69 5d 2e 70 57 6f 72 6b 65 72 2c 20 31  er[i].pWorker, 1
5bb0: 2c 20 7a 53 74 72 2c 20 30 29 3b 0a 20 20 20 20  , zStr, 0);.    
5bc0: 7d 0a 23 65 6e 64 69 66 0a 20 20 7d 0a 20 20 72  }.#endif.  }.  r
5bd0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74  eturn rc;.}..int
5be0: 20 74 64 62 5f 6c 73 6d 5f 63 6f 6e 66 69 67 75   tdb_lsm_configu
5bf0: 72 65 28 6c 73 6d 5f 64 62 20 2a 64 62 2c 20 63  re(lsm_db *db, c
5c00: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 6f 6e 66  onst char *zConf
5c10: 69 67 29 7b 0a 20 20 72 65 74 75 72 6e 20 74 65  ig){.  return te
5c20: 73 74 5f 6c 73 6d 5f 63 6f 6e 66 69 67 5f 73 74  st_lsm_config_st
5c30: 72 28 30 2c 20 64 62 2c 20 30 2c 20 7a 43 6f 6e  r(0, db, 0, zCon
5c40: 66 69 67 2c 20 30 29 3b 0a 7d 0a 0a 73 74 61 74  fig, 0);.}..stat
5c50: 69 63 20 69 6e 74 20 74 65 73 74 4c 73 6d 53 74  ic int testLsmSt
5c60: 61 72 74 57 6f 72 6b 65 72 73 28 4c 73 6d 44 62  artWorkers(LsmDb
5c70: 20 2a 2c 20 69 6e 74 2c 20 63 6f 6e 73 74 20 63   *, int, const c
5c80: 68 61 72 20 2a 2c 20 63 6f 6e 73 74 20 63 68 61  har *, const cha
5c90: 72 20 2a 29 3b 0a 0a 73 74 61 74 69 63 20 69 6e  r *);..static in
5ca0: 74 20 74 65 73 74 4c 73 6d 4f 70 65 6e 28 0a 20  t testLsmOpen(. 
5cb0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 66   const char *zCf
5cc0: 67 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  g,.  const char 
5cd0: 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 0a 20 20 69  *zFilename, .  i
5ce0: 6e 74 20 62 43 6c 65 61 72 2c 20 0a 20 20 54 65  nt bClear, .  Te
5cf0: 73 74 44 62 20 2a 2a 70 70 44 62 0a 29 7b 0a 20  stDb **ppDb.){. 
5d00: 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20 44 61   static const Da
5d10: 74 61 62 61 73 65 4d 65 74 68 6f 64 73 20 4c 73  tabaseMethods Ls
5d20: 6d 4d 65 74 68 6f 64 73 20 3d 20 7b 0a 20 20 20  mMethods = {.   
5d30: 20 74 65 73 74 5f 6c 73 6d 5f 63 6c 6f 73 65 2c   test_lsm_close,
5d40: 0a 20 20 20 20 74 65 73 74 5f 6c 73 6d 5f 77 72  .    test_lsm_wr
5d50: 69 74 65 2c 0a 20 20 20 20 74 65 73 74 5f 6c 73  ite,.    test_ls
5d60: 6d 5f 64 65 6c 65 74 65 2c 0a 20 20 20 20 74 65  m_delete,.    te
5d70: 73 74 5f 6c 73 6d 5f 64 65 6c 65 74 65 5f 72 61  st_lsm_delete_ra
5d80: 6e 67 65 2c 0a 20 20 20 20 74 65 73 74 5f 6c 73  nge,.    test_ls
5d90: 6d 5f 66 65 74 63 68 2c 0a 20 20 20 20 74 65 73  m_fetch,.    tes
5da0: 74 5f 6c 73 6d 5f 73 63 61 6e 2c 0a 20 20 20 20  t_lsm_scan,.    
5db0: 74 65 73 74 5f 6c 73 6d 5f 62 65 67 69 6e 2c 0a  test_lsm_begin,.
5dc0: 20 20 20 20 74 65 73 74 5f 6c 73 6d 5f 63 6f 6d      test_lsm_com
5dd0: 6d 69 74 2c 0a 20 20 20 20 74 65 73 74 5f 6c 73  mit,.    test_ls
5de0: 6d 5f 72 6f 6c 6c 62 61 63 6b 0a 20 20 7d 3b 0a  m_rollback.  };.
5df0: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74  .  int rc;.  int
5e00: 20 6e 46 69 6c 65 6e 61 6d 65 3b 0a 20 20 4c 73   nFilename;.  Ls
5e10: 6d 44 62 20 2a 70 44 62 3b 0a 0a 20 20 2f 2a 20  mDb *pDb;..  /* 
5e20: 49 66 20 74 68 65 20 62 43 6c 65 61 72 20 66 6c  If the bClear fl
5e30: 61 67 20 69 73 20 73 65 74 2c 20 64 65 6c 65 74  ag is set, delet
5e40: 65 20 61 6e 79 20 65 78 69 73 74 69 6e 67 20 64  e any existing d
5e50: 61 74 61 62 61 73 65 2e 20 2a 2f 0a 20 20 61 73  atabase. */.  as
5e60: 73 65 72 74 28 20 7a 46 69 6c 65 6e 61 6d 65 29  sert( zFilename)
5e70: 3b 0a 20 20 69 66 28 20 62 43 6c 65 61 72 20 29  ;.  if( bClear )
5e80: 20 74 65 73 74 44 65 6c 65 74 65 4c 73 6d 64 62   testDeleteLsmdb
5e90: 28 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 6e  (zFilename);.  n
5ea0: 46 69 6c 65 6e 61 6d 65 20 3d 20 73 74 72 6c 65  Filename = strle
5eb0: 6e 28 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 0a 20  n(zFilename);.. 
5ec0: 20 70 44 62 20 3d 20 28 4c 73 6d 44 62 20 2a 29   pDb = (LsmDb *)
5ed0: 74 65 73 74 4d 61 6c 6c 6f 63 28 73 69 7a 65 6f  testMalloc(sizeo
5ee0: 66 28 4c 73 6d 44 62 29 20 2b 20 6e 46 69 6c 65  f(LsmDb) + nFile
5ef0: 6e 61 6d 65 20 2b 20 31 29 3b 0a 20 20 6d 65 6d  name + 1);.  mem
5f00: 73 65 74 28 70 44 62 2c 20 30 2c 20 73 69 7a 65  set(pDb, 0, size
5f10: 6f 66 28 4c 73 6d 44 62 29 29 3b 0a 20 20 70 44  of(LsmDb));.  pD
5f20: 62 2d 3e 62 61 73 65 2e 70 4d 65 74 68 6f 64 73  b->base.pMethods
5f30: 20 3d 20 26 4c 73 6d 4d 65 74 68 6f 64 73 3b 0a   = &LsmMethods;.
5f40: 20 20 70 44 62 2d 3e 7a 4e 61 6d 65 20 3d 20 28    pDb->zName = (
5f50: 63 68 61 72 20 2a 29 26 70 44 62 5b 31 5d 3b 0a  char *)&pDb[1];.
5f60: 20 20 6d 65 6d 63 70 79 28 70 44 62 2d 3e 7a 4e    memcpy(pDb->zN
5f70: 61 6d 65 2c 20 7a 46 69 6c 65 6e 61 6d 65 2c 20  ame, zFilename, 
5f80: 6e 46 69 6c 65 6e 61 6d 65 20 2b 20 31 29 3b 0a  nFilename + 1);.
5f90: 0a 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 74 68  .  /* Default th
5fa0: 65 20 73 65 63 74 6f 72 20 73 69 7a 65 20 75 73  e sector size us
5fb0: 65 64 20 66 6f 72 20 63 72 61 73 68 20 73 69 6d  ed for crash sim
5fc0: 75 6c 61 74 69 6f 6e 20 74 6f 20 35 31 32 20 62  ulation to 512 b
5fd0: 79 74 65 73 2e 20 0a 20 20 2a 2a 20 54 6f 64 6f  ytes. .  ** Todo
5fe0: 3a 20 54 68 65 72 65 20 73 68 6f 75 6c 64 20 62  : There should b
5ff0: 65 20 61 6e 20 4f 53 20 6d 65 74 68 6f 64 20 74  e an OS method t
6000: 6f 20 6f 62 74 61 69 6e 20 74 68 69 73 20 76 61  o obtain this va
6010: 6c 75 65 20 2d 20 6a 75 73 74 20 61 73 0a 20 20  lue - just as.  
6020: 2a 2a 20 74 68 65 72 65 20 69 73 20 69 6e 20 53  ** there is in S
6030: 51 4c 69 74 65 2e 20 46 6f 72 20 6e 6f 77 2c 20  QLite. For now, 
6040: 4c 53 4d 20 61 73 73 75 6d 65 73 20 74 68 61 74  LSM assumes that
6050: 20 69 74 20 69 73 20 73 6d 61 6c 6c 65 72 20 74   it is smaller t
6060: 68 61 6e 0a 20 20 2a 2a 20 74 68 65 20 70 61 67  han.  ** the pag
6070: 65 20 73 69 7a 65 20 28 64 65 66 61 75 6c 74 20  e size (default 
6080: 34 4b 42 29 2e 0a 20 20 2a 2f 0a 20 20 70 44 62  4KB)..  */.  pDb
6090: 2d 3e 73 7a 53 65 63 74 6f 72 20 3d 20 32 35 36  ->szSector = 256
60a0: 3b 0a 0a 20 20 2f 2a 20 44 65 66 61 75 6c 74 20  ;..  /* Default 
60b0: 76 61 6c 75 65 73 20 66 6f 72 20 74 68 65 20 6d  values for the m
60c0: 74 5f 6d 69 6e 5f 63 6b 70 74 20 61 6e 64 20 6d  t_min_ckpt and m
60d0: 74 5f 6d 61 78 5f 63 6b 70 74 20 70 61 72 61 6d  t_max_ckpt param
60e0: 65 74 65 72 73 2e 20 2a 2f 0a 20 20 70 44 62 2d  eters. */.  pDb-
60f0: 3e 6e 4d 74 4d 69 6e 43 6b 70 74 20 3d 20 4c 53  >nMtMinCkpt = LS
6100: 4d 54 45 53 54 5f 44 46 4c 54 5f 4d 54 5f 4d 49  MTEST_DFLT_MT_MI
6110: 4e 5f 43 4b 50 54 3b 0a 20 20 70 44 62 2d 3e 6e  N_CKPT;.  pDb->n
6120: 4d 74 4d 61 78 43 6b 70 74 20 3d 20 4c 53 4d 54  MtMaxCkpt = LSMT
6130: 45 53 54 5f 44 46 4c 54 5f 4d 54 5f 4d 41 58 5f  EST_DFLT_MT_MAX_
6140: 43 4b 50 54 3b 0a 0a 20 20 6d 65 6d 63 70 79 28  CKPT;..  memcpy(
6150: 26 70 44 62 2d 3e 65 6e 76 2c 20 74 64 62 5f 6c  &pDb->env, tdb_l
6160: 73 6d 5f 65 6e 76 28 29 2c 20 73 69 7a 65 6f 66  sm_env(), sizeof
6170: 28 6c 73 6d 5f 65 6e 76 29 29 3b 0a 20 20 70 44  (lsm_env));.  pD
6180: 62 2d 3e 65 6e 76 2e 70 56 66 73 43 74 78 20 3d  b->env.pVfsCtx =
6190: 20 28 76 6f 69 64 20 2a 29 70 44 62 3b 0a 20 20   (void *)pDb;.  
61a0: 70 44 62 2d 3e 65 6e 76 2e 78 46 75 6c 6c 70 61  pDb->env.xFullpa
61b0: 74 68 20 3d 20 74 65 73 74 45 6e 76 46 75 6c 6c  th = testEnvFull
61c0: 70 61 74 68 3b 0a 20 20 70 44 62 2d 3e 65 6e 76  path;.  pDb->env
61d0: 2e 78 4f 70 65 6e 20 3d 20 74 65 73 74 45 6e 76  .xOpen = testEnv
61e0: 4f 70 65 6e 3b 0a 20 20 70 44 62 2d 3e 65 6e 76  Open;.  pDb->env
61f0: 2e 78 52 65 61 64 20 3d 20 74 65 73 74 45 6e 76  .xRead = testEnv
6200: 52 65 61 64 3b 0a 20 20 70 44 62 2d 3e 65 6e 76  Read;.  pDb->env
6210: 2e 78 57 72 69 74 65 20 3d 20 74 65 73 74 45 6e  .xWrite = testEn
6220: 76 57 72 69 74 65 3b 0a 20 20 70 44 62 2d 3e 65  vWrite;.  pDb->e
6230: 6e 76 2e 78 54 72 75 6e 63 61 74 65 20 3d 20 74  nv.xTruncate = t
6240: 65 73 74 45 6e 76 54 72 75 6e 63 61 74 65 3b 0a  estEnvTruncate;.
6250: 20 20 70 44 62 2d 3e 65 6e 76 2e 78 53 79 6e 63    pDb->env.xSync
6260: 20 3d 20 74 65 73 74 45 6e 76 53 79 6e 63 3b 0a   = testEnvSync;.
6270: 20 20 70 44 62 2d 3e 65 6e 76 2e 78 53 65 63 74    pDb->env.xSect
6280: 6f 72 53 69 7a 65 20 3d 20 74 65 73 74 45 6e 76  orSize = testEnv
6290: 53 65 63 74 6f 72 53 69 7a 65 3b 0a 20 20 70 44  SectorSize;.  pD
62a0: 62 2d 3e 65 6e 76 2e 78 52 65 6d 61 70 20 3d 20  b->env.xRemap = 
62b0: 74 65 73 74 45 6e 76 52 65 6d 61 70 3b 0a 20 20  testEnvRemap;.  
62c0: 70 44 62 2d 3e 65 6e 76 2e 78 46 69 6c 65 69 64  pDb->env.xFileid
62d0: 20 3d 20 74 65 73 74 45 6e 76 46 69 6c 65 69 64   = testEnvFileid
62e0: 3b 0a 20 20 70 44 62 2d 3e 65 6e 76 2e 78 43 6c  ;.  pDb->env.xCl
62f0: 6f 73 65 20 3d 20 74 65 73 74 45 6e 76 43 6c 6f  ose = testEnvClo
6300: 73 65 3b 0a 20 20 70 44 62 2d 3e 65 6e 76 2e 78  se;.  pDb->env.x
6310: 55 6e 6c 69 6e 6b 20 3d 20 74 65 73 74 45 6e 76  Unlink = testEnv
6320: 55 6e 6c 69 6e 6b 3b 0a 20 20 70 44 62 2d 3e 65  Unlink;.  pDb->e
6330: 6e 76 2e 78 4c 6f 63 6b 20 3d 20 74 65 73 74 45  nv.xLock = testE
6340: 6e 76 4c 6f 63 6b 3b 0a 20 20 70 44 62 2d 3e 65  nvLock;.  pDb->e
6350: 6e 76 2e 78 54 65 73 74 4c 6f 63 6b 20 3d 20 74  nv.xTestLock = t
6360: 65 73 74 45 6e 76 54 65 73 74 4c 6f 63 6b 3b 0a  estEnvTestLock;.
6370: 20 20 70 44 62 2d 3e 65 6e 76 2e 78 53 68 6d 42    pDb->env.xShmB
6380: 61 72 72 69 65 72 20 3d 20 74 65 73 74 45 6e 76  arrier = testEnv
6390: 53 68 6d 42 61 72 72 69 65 72 3b 0a 20 20 70 44  ShmBarrier;.  pD
63a0: 62 2d 3e 65 6e 76 2e 78 53 68 6d 4d 61 70 20 3d  b->env.xShmMap =
63b0: 20 74 65 73 74 45 6e 76 53 68 6d 4d 61 70 3b 0a   testEnvShmMap;.
63c0: 20 20 70 44 62 2d 3e 65 6e 76 2e 78 53 68 6d 55    pDb->env.xShmU
63d0: 6e 6d 61 70 20 3d 20 74 65 73 74 45 6e 76 53 68  nmap = testEnvSh
63e0: 6d 55 6e 6d 61 70 3b 0a 20 20 70 44 62 2d 3e 65  mUnmap;.  pDb->e
63f0: 6e 76 2e 78 53 6c 65 65 70 20 3d 20 74 65 73 74  nv.xSleep = test
6400: 45 6e 76 53 6c 65 65 70 3b 0a 0a 20 20 72 63 20  EnvSleep;..  rc 
6410: 3d 20 6c 73 6d 5f 6e 65 77 28 26 70 44 62 2d 3e  = lsm_new(&pDb->
6420: 65 6e 76 2c 20 26 70 44 62 2d 3e 64 62 29 3b 0a  env, &pDb->db);.
6430: 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b    if( rc==LSM_OK
6440: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 54 68 72   ){.    int nThr
6450: 65 61 64 20 3d 20 31 3b 0a 20 20 20 20 6c 73 6d  ead = 1;.    lsm
6460: 5f 63 6f 6e 66 69 67 5f 6c 6f 67 28 70 44 62 2d  _config_log(pDb-
6470: 3e 64 62 2c 20 78 4c 6f 67 2c 20 30 29 3b 0a 20  >db, xLog, 0);. 
6480: 20 20 20 6c 73 6d 5f 63 6f 6e 66 69 67 5f 77 6f     lsm_config_wo
6490: 72 6b 5f 68 6f 6f 6b 28 70 44 62 2d 3e 64 62 2c  rk_hook(pDb->db,
64a0: 20 78 57 6f 72 6b 48 6f 6f 6b 2c 20 28 76 6f 69   xWorkHook, (voi
64b0: 64 20 2a 29 70 44 62 29 3b 0a 0a 20 20 20 20 72  d *)pDb);..    r
64c0: 63 20 3d 20 74 65 73 74 5f 6c 73 6d 5f 63 6f 6e  c = test_lsm_con
64d0: 66 69 67 5f 73 74 72 28 70 44 62 2c 20 70 44 62  fig_str(pDb, pDb
64e0: 2d 3e 64 62 2c 20 30 2c 20 7a 43 66 67 2c 20 26  ->db, 0, zCfg, &
64f0: 6e 54 68 72 65 61 64 29 3b 0a 20 20 20 20 69 66  nThread);.    if
6500: 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 20 72  ( rc==LSM_OK ) r
6510: 63 20 3d 20 6c 73 6d 5f 6f 70 65 6e 28 70 44 62  c = lsm_open(pDb
6520: 2d 3e 64 62 2c 20 7a 46 69 6c 65 6e 61 6d 65 29  ->db, zFilename)
6530: 3b 0a 0a 20 20 20 20 70 44 62 2d 3e 65 4d 6f 64  ;..    pDb->eMod
6540: 65 20 3d 20 6e 54 68 72 65 61 64 3b 0a 23 69 66  e = nThread;.#if
6550: 64 65 66 20 4c 53 4d 5f 4d 55 54 45 58 5f 50 54  def LSM_MUTEX_PT
6560: 48 52 45 41 44 53 0a 20 20 20 20 69 66 28 20 72  HREADS.    if( r
6570: 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 6e 54 68  c==LSM_OK && nTh
6580: 72 65 61 64 3e 31 20 29 7b 0a 20 20 20 20 20 20  read>1 ){.      
6590: 74 65 73 74 4c 73 6d 53 74 61 72 74 57 6f 72 6b  testLsmStartWork
65a0: 65 72 73 28 70 44 62 2c 20 6e 54 68 72 65 61 64  ers(pDb, nThread
65b0: 2c 20 7a 46 69 6c 65 6e 61 6d 65 2c 20 7a 43 66  , zFilename, zCf
65c0: 67 29 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66  g);.    }.#endif
65d0: 0a 0a 20 20 20 20 69 66 28 20 72 63 21 3d 4c 53  ..    if( rc!=LS
65e0: 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 74 65  M_OK ){.      te
65f0: 73 74 5f 6c 73 6d 5f 63 6c 6f 73 65 28 28 54 65  st_lsm_close((Te
6600: 73 74 44 62 20 2a 29 70 44 62 29 3b 0a 20 20 20  stDb *)pDb);.   
6610: 20 20 20 70 44 62 20 3d 20 30 3b 0a 20 20 20 20     pDb = 0;.    
6620: 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 44 62 20 3d  }.  }..  *ppDb =
6630: 20 28 54 65 73 74 44 62 20 2a 29 70 44 62 3b 0a   (TestDb *)pDb;.
6640: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
6650: 69 6e 74 20 74 65 73 74 5f 6c 73 6d 5f 6f 70 65  int test_lsm_ope
6660: 6e 28 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  n(.  const char 
6670: 2a 7a 53 70 65 63 2c 20 0a 20 20 63 6f 6e 73 74  *zSpec, .  const
6680: 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65   char *zFilename
6690: 2c 20 0a 20 20 69 6e 74 20 62 43 6c 65 61 72 2c  , .  int bClear,
66a0: 20 0a 20 20 54 65 73 74 44 62 20 2a 2a 70 70 44   .  TestDb **ppD
66b0: 62 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20 74 65  b.){.  return te
66c0: 73 74 4c 73 6d 4f 70 65 6e 28 22 22 2c 20 7a 46  stLsmOpen("", zF
66d0: 69 6c 65 6e 61 6d 65 2c 20 62 43 6c 65 61 72 2c  ilename, bClear,
66e0: 20 70 70 44 62 29 3b 0a 7d 0a 0a 69 6e 74 20 74   ppDb);.}..int t
66f0: 65 73 74 5f 6c 73 6d 5f 73 6d 61 6c 6c 5f 6f 70  est_lsm_small_op
6700: 65 6e 28 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  en(.  const char
6710: 20 2a 7a 53 70 65 63 2c 20 0a 20 20 63 6f 6e 73   *zSpec, .  cons
6720: 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 2c 20 0a  t char *zFile, .
6730: 20 20 69 6e 74 20 62 43 6c 65 61 72 2c 20 0a 20    int bClear, . 
6740: 20 54 65 73 74 44 62 20 2a 2a 70 70 44 62 0a 29   TestDb **ppDb.)
6750: 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  {.  const char *
6760: 7a 43 66 67 20 3d 20 22 70 61 67 65 5f 73 69 7a  zCfg = "page_siz
6770: 65 3d 32 35 36 20 62 6c 6f 63 6b 5f 73 69 7a 65  e=256 block_size
6780: 3d 36 34 20 6d 6d 61 70 3d 31 30 32 34 22 3b 0a  =64 mmap=1024";.
6790: 20 20 72 65 74 75 72 6e 20 74 65 73 74 4c 73 6d    return testLsm
67a0: 4f 70 65 6e 28 7a 43 66 67 2c 20 7a 46 69 6c 65  Open(zCfg, zFile
67b0: 2c 20 62 43 6c 65 61 72 2c 20 70 70 44 62 29 3b  , bClear, ppDb);
67c0: 0a 7d 0a 0a 69 6e 74 20 74 65 73 74 5f 6c 73 6d  .}..int test_lsm
67d0: 5f 6c 6f 6d 65 6d 5f 6f 70 65 6e 28 0a 20 20 63  _lomem_open(.  c
67e0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 70 65 63  onst char *zSpec
67f0: 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  , .  const char 
6800: 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 0a 20 20 69  *zFilename, .  i
6810: 6e 74 20 62 43 6c 65 61 72 2c 20 0a 20 20 54 65  nt bClear, .  Te
6820: 73 74 44 62 20 2a 2a 70 70 44 62 0a 29 7b 0a 20  stDb **ppDb.){. 
6830: 20 20 20 2f 2a 20 22 6d 61 78 5f 66 72 65 65 6c     /* "max_freel
6840: 69 73 74 3d 34 20 61 75 74 6f 63 68 65 63 6b 70  ist=4 autocheckp
6850: 6f 69 6e 74 3d 33 32 22 20 2a 2f 0a 20 20 63 6f  oint=32" */.  co
6860: 6e 73 74 20 63 68 61 72 20 2a 7a 43 66 67 20 3d  nst char *zCfg =
6870: 20 0a 20 20 20 20 22 70 61 67 65 5f 73 69 7a 65   .    "page_size
6880: 3d 32 35 36 20 62 6c 6f 63 6b 5f 73 69 7a 65 3d  =256 block_size=
6890: 36 34 20 61 75 74 6f 66 6c 75 73 68 3d 31 36 20  64 autoflush=16 
68a0: 22 0a 20 20 20 20 22 61 75 74 6f 63 68 65 63 6b  ".    "autocheck
68b0: 70 6f 69 6e 74 3d 33 32 22 0a 20 20 20 20 22 6d  point=32".    "m
68c0: 6d 61 70 3d 30 20 22 0a 20 20 3b 0a 20 20 72 65  map=0 ".  ;.  re
68d0: 74 75 72 6e 20 74 65 73 74 4c 73 6d 4f 70 65 6e  turn testLsmOpen
68e0: 28 7a 43 66 67 2c 20 7a 46 69 6c 65 6e 61 6d 65  (zCfg, zFilename
68f0: 2c 20 62 43 6c 65 61 72 2c 20 70 70 44 62 29 3b  , bClear, ppDb);
6900: 0a 7d 0a 0a 69 6e 74 20 74 65 73 74 5f 6c 73 6d  .}..int test_lsm
6910: 5f 7a 69 70 5f 6f 70 65 6e 28 0a 20 20 63 6f 6e  _zip_open(.  con
6920: 73 74 20 63 68 61 72 20 2a 7a 53 70 65 63 2c 20  st char *zSpec, 
6930: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
6940: 46 69 6c 65 6e 61 6d 65 2c 20 0a 20 20 69 6e 74  Filename, .  int
6950: 20 62 43 6c 65 61 72 2c 20 0a 20 20 54 65 73 74   bClear, .  Test
6960: 44 62 20 2a 2a 70 70 44 62 0a 29 7b 0a 20 20 63  Db **ppDb.){.  c
6970: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 66 67 20  onst char *zCfg 
6980: 3d 20 0a 20 20 20 20 22 70 61 67 65 5f 73 69 7a  = .    "page_siz
6990: 65 3d 32 35 36 20 62 6c 6f 63 6b 5f 73 69 7a 65  e=256 block_size
69a0: 3d 36 34 20 61 75 74 6f 66 6c 75 73 68 3d 31 36  =64 autoflush=16
69b0: 20 22 0a 20 20 20 20 22 61 75 74 6f 63 68 65 63   ".    "autochec
69c0: 6b 70 6f 69 6e 74 3d 33 32 20 63 6f 6d 70 72 65  kpoint=32 compre
69d0: 73 73 69 6f 6e 3d 31 20 6d 6d 61 70 3d 30 20 22  ssion=1 mmap=0 "
69e0: 0a 20 20 3b 0a 20 20 72 65 74 75 72 6e 20 74 65  .  ;.  return te
69f0: 73 74 4c 73 6d 4f 70 65 6e 28 7a 43 66 67 2c 20  stLsmOpen(zCfg, 
6a00: 7a 46 69 6c 65 6e 61 6d 65 2c 20 62 43 6c 65 61  zFilename, bClea
6a10: 72 2c 20 70 70 44 62 29 3b 0a 7d 0a 0a 6c 73 6d  r, ppDb);.}..lsm
6a20: 5f 64 62 20 2a 74 64 62 5f 6c 73 6d 28 54 65 73  _db *tdb_lsm(Tes
6a30: 74 44 62 20 2a 70 44 62 29 7b 0a 20 20 69 66 28  tDb *pDb){.  if(
6a40: 20 70 44 62 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e   pDb->pMethods->
6a50: 78 43 6c 6f 73 65 3d 3d 74 65 73 74 5f 6c 73 6d  xClose==test_lsm
6a60: 5f 63 6c 6f 73 65 20 29 7b 0a 20 20 20 20 72 65  _close ){.    re
6a70: 74 75 72 6e 20 28 28 4c 73 6d 44 62 20 2a 29 70  turn ((LsmDb *)p
6a80: 44 62 29 2d 3e 64 62 3b 0a 20 20 7d 0a 20 20 72  Db)->db;.  }.  r
6a90: 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 76 6f 69 64  eturn 0;.}..void
6aa0: 20 74 64 62 5f 6c 73 6d 5f 65 6e 61 62 6c 65 5f   tdb_lsm_enable_
6ab0: 6c 6f 67 28 54 65 73 74 44 62 20 2a 70 44 62 2c  log(TestDb *pDb,
6ac0: 20 69 6e 74 20 62 45 6e 61 62 6c 65 29 7b 0a 20   int bEnable){. 
6ad0: 20 6c 73 6d 5f 64 62 20 2a 64 62 20 3d 20 74 64   lsm_db *db = td
6ae0: 62 5f 6c 73 6d 28 70 44 62 29 3b 0a 20 20 69 66  b_lsm(pDb);.  if
6af0: 28 20 64 62 20 29 7b 0a 20 20 20 20 6c 73 6d 5f  ( db ){.    lsm_
6b00: 63 6f 6e 66 69 67 5f 6c 6f 67 28 64 62 2c 20 28  config_log(db, (
6b10: 62 45 6e 61 62 6c 65 20 3f 20 78 4c 6f 67 20 3a  bEnable ? xLog :
6b20: 20 30 29 2c 20 28 76 6f 69 64 20 2a 29 22 63 6c   0), (void *)"cl
6b30: 69 65 6e 74 22 29 3b 0a 20 20 7d 0a 7d 0a 0a 76  ient");.  }.}..v
6b40: 6f 69 64 20 74 64 62 5f 6c 73 6d 5f 61 70 70 6c  oid tdb_lsm_appl
6b50: 69 63 61 74 69 6f 6e 5f 63 72 61 73 68 28 54 65  ication_crash(Te
6b60: 73 74 44 62 20 2a 70 44 62 29 7b 0a 20 20 69 66  stDb *pDb){.  if
6b70: 28 20 74 64 62 5f 6c 73 6d 28 70 44 62 29 20 29  ( tdb_lsm(pDb) )
6b80: 7b 0a 20 20 20 20 4c 73 6d 44 62 20 2a 70 20 3d  {.    LsmDb *p =
6b90: 20 28 4c 73 6d 44 62 20 2a 29 70 44 62 3b 0a 20   (LsmDb *)pDb;. 
6ba0: 20 20 20 70 2d 3e 62 43 72 61 73 68 65 64 20 3d     p->bCrashed =
6bb0: 20 31 3b 0a 20 20 7d 0a 7d 0a 0a 76 6f 69 64 20   1;.  }.}..void 
6bc0: 74 64 62 5f 6c 73 6d 5f 70 72 65 70 61 72 65 5f  tdb_lsm_prepare_
6bd0: 73 79 73 74 65 6d 5f 63 72 61 73 68 28 54 65 73  system_crash(Tes
6be0: 74 44 62 20 2a 70 44 62 29 7b 0a 20 20 69 66 28  tDb *pDb){.  if(
6bf0: 20 74 64 62 5f 6c 73 6d 28 70 44 62 29 20 29 7b   tdb_lsm(pDb) ){
6c00: 0a 20 20 20 20 4c 73 6d 44 62 20 2a 70 20 3d 20  .    LsmDb *p = 
6c10: 28 4c 73 6d 44 62 20 2a 29 70 44 62 3b 0a 20 20  (LsmDb *)pDb;.  
6c20: 20 20 70 2d 3e 62 50 72 65 70 61 72 65 43 72 61    p->bPrepareCra
6c30: 73 68 20 3d 20 31 3b 0a 20 20 7d 0a 7d 0a 0a 76  sh = 1;.  }.}..v
6c40: 6f 69 64 20 74 64 62 5f 6c 73 6d 5f 73 79 73 74  oid tdb_lsm_syst
6c50: 65 6d 5f 63 72 61 73 68 28 54 65 73 74 44 62 20  em_crash(TestDb 
6c60: 2a 70 44 62 29 7b 0a 20 20 69 66 28 20 74 64 62  *pDb){.  if( tdb
6c70: 5f 6c 73 6d 28 70 44 62 29 20 29 7b 0a 20 20 20  _lsm(pDb) ){.   
6c80: 20 4c 73 6d 44 62 20 2a 70 20 3d 20 28 4c 73 6d   LsmDb *p = (Lsm
6c90: 44 62 20 2a 29 70 44 62 3b 0a 20 20 20 20 70 2d  Db *)pDb;.    p-
6ca0: 3e 62 43 72 61 73 68 65 64 20 3d 20 31 3b 0a 20  >bCrashed = 1;. 
6cb0: 20 20 20 64 6f 53 79 73 74 65 6d 43 72 61 73 68     doSystemCrash
6cc0: 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 76 6f 69 64  (p);.  }.}..void
6cd0: 20 74 64 62 5f 6c 73 6d 5f 73 61 66 65 74 79 28   tdb_lsm_safety(
6ce0: 54 65 73 74 44 62 20 2a 70 44 62 2c 20 69 6e 74  TestDb *pDb, int
6cf0: 20 65 4d 6f 64 65 29 7b 0a 20 20 61 73 73 65 72   eMode){.  asser
6d00: 74 28 20 65 4d 6f 64 65 3d 3d 4c 53 4d 5f 53 41  t( eMode==LSM_SA
6d10: 46 45 54 59 5f 4f 46 46 20 0a 20 20 20 20 20 20  FETY_OFF .      
6d20: 20 7c 7c 20 65 4d 6f 64 65 3d 3d 4c 53 4d 5f 53   || eMode==LSM_S
6d30: 41 46 45 54 59 5f 4e 4f 52 4d 41 4c 20 0a 20 20  AFETY_NORMAL .  
6d40: 20 20 20 20 20 7c 7c 20 65 4d 6f 64 65 3d 3d 4c       || eMode==L
6d50: 53 4d 5f 53 41 46 45 54 59 5f 46 55 4c 4c 20 0a  SM_SAFETY_FULL .
6d60: 20 20 29 3b 0a 20 20 69 66 28 20 74 64 62 5f 6c    );.  if( tdb_l
6d70: 73 6d 28 70 44 62 29 20 29 7b 0a 20 20 20 20 69  sm(pDb) ){.    i
6d80: 6e 74 20 69 50 61 72 61 6d 20 3d 20 65 4d 6f 64  nt iParam = eMod
6d90: 65 3b 0a 20 20 20 20 4c 73 6d 44 62 20 2a 70 20  e;.    LsmDb *p 
6da0: 3d 20 28 4c 73 6d 44 62 20 2a 29 70 44 62 3b 0a  = (LsmDb *)pDb;.
6db0: 20 20 20 20 6c 73 6d 5f 63 6f 6e 66 69 67 28 70      lsm_config(p
6dc0: 2d 3e 64 62 2c 20 4c 53 4d 5f 43 4f 4e 46 49 47  ->db, LSM_CONFIG
6dd0: 5f 53 41 46 45 54 59 2c 20 26 69 50 61 72 61 6d  _SAFETY, &iParam
6de0: 29 3b 0a 20 20 7d 0a 7d 0a 0a 76 6f 69 64 20 74  );.  }.}..void t
6df0: 64 62 5f 6c 73 6d 5f 70 72 65 70 61 72 65 5f 73  db_lsm_prepare_s
6e00: 79 6e 63 5f 63 72 61 73 68 28 54 65 73 74 44 62  ync_crash(TestDb
6e10: 20 2a 70 44 62 2c 20 69 6e 74 20 69 53 79 6e 63   *pDb, int iSync
6e20: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 69 53 79  ){.  assert( iSy
6e30: 6e 63 3e 30 20 29 3b 0a 20 20 69 66 28 20 74 64  nc>0 );.  if( td
6e40: 62 5f 6c 73 6d 28 70 44 62 29 20 29 7b 0a 20 20  b_lsm(pDb) ){.  
6e50: 20 20 4c 73 6d 44 62 20 2a 70 20 3d 20 28 4c 73    LsmDb *p = (Ls
6e60: 6d 44 62 20 2a 29 70 44 62 3b 0a 20 20 20 20 70  mDb *)pDb;.    p
6e70: 2d 3e 6e 41 75 74 6f 43 72 61 73 68 20 3d 20 69  ->nAutoCrash = i
6e80: 53 79 6e 63 3b 0a 20 20 20 20 70 2d 3e 62 50 72  Sync;.    p->bPr
6e90: 65 70 61 72 65 43 72 61 73 68 20 3d 20 31 3b 0a  epareCrash = 1;.
6ea0: 20 20 7d 0a 7d 0a 0a 76 6f 69 64 20 74 64 62 5f    }.}..void tdb_
6eb0: 6c 73 6d 5f 63 6f 6e 66 69 67 5f 77 6f 72 6b 5f  lsm_config_work_
6ec0: 68 6f 6f 6b 28 0a 20 20 54 65 73 74 44 62 20 2a  hook(.  TestDb *
6ed0: 70 44 62 2c 20 0a 20 20 76 6f 69 64 20 28 2a 78  pDb, .  void (*x
6ee0: 57 6f 72 6b 29 28 6c 73 6d 5f 64 62 20 2a 2c 20  Work)(lsm_db *, 
6ef0: 76 6f 69 64 20 2a 29 2c 20 0a 20 20 76 6f 69 64  void *), .  void
6f00: 20 2a 70 57 6f 72 6b 43 74 78 0a 29 7b 0a 20 20   *pWorkCtx.){.  
6f10: 69 66 28 20 74 64 62 5f 6c 73 6d 28 70 44 62 29  if( tdb_lsm(pDb)
6f20: 20 29 7b 0a 20 20 20 20 4c 73 6d 44 62 20 2a 70   ){.    LsmDb *p
6f30: 20 3d 20 28 4c 73 6d 44 62 20 2a 29 70 44 62 3b   = (LsmDb *)pDb;
6f40: 0a 20 20 20 20 70 2d 3e 78 57 6f 72 6b 20 3d 20  .    p->xWork = 
6f50: 78 57 6f 72 6b 3b 0a 20 20 20 20 70 2d 3e 70 57  xWork;.    p->pW
6f60: 6f 72 6b 43 74 78 20 3d 20 70 57 6f 72 6b 43 74  orkCtx = pWorkCt
6f70: 78 3b 0a 20 20 7d 0a 7d 0a 0a 76 6f 69 64 20 74  x;.  }.}..void t
6f80: 64 62 5f 6c 73 6d 5f 77 72 69 74 65 5f 68 6f 6f  db_lsm_write_hoo
6f90: 6b 28 0a 20 20 54 65 73 74 44 62 20 2a 70 44 62  k(.  TestDb *pDb
6fa0: 2c 20 0a 20 20 76 6f 69 64 20 28 2a 78 57 72 69  , .  void (*xWri
6fb0: 74 65 29 28 76 6f 69 64 20 2a 2c 20 69 6e 74 2c  te)(void *, int,
6fc0: 20 6c 73 6d 5f 69 36 34 2c 20 69 6e 74 2c 20 69   lsm_i64, int, i
6fd0: 6e 74 29 2c 0a 20 20 76 6f 69 64 20 2a 70 57 72  nt),.  void *pWr
6fe0: 69 74 65 43 74 78 0a 29 7b 0a 20 20 69 66 28 20  iteCtx.){.  if( 
6ff0: 74 64 62 5f 6c 73 6d 28 70 44 62 29 20 29 7b 0a  tdb_lsm(pDb) ){.
7000: 20 20 20 20 4c 73 6d 44 62 20 2a 70 20 3d 20 28      LsmDb *p = (
7010: 4c 73 6d 44 62 20 2a 29 70 44 62 3b 0a 20 20 20  LsmDb *)pDb;.   
7020: 20 70 2d 3e 78 57 72 69 74 65 48 6f 6f 6b 20 3d   p->xWriteHook =
7030: 20 78 57 72 69 74 65 3b 0a 20 20 20 20 70 2d 3e   xWrite;.    p->
7040: 70 57 72 69 74 65 43 74 78 20 3d 20 70 57 72 69  pWriteCtx = pWri
7050: 74 65 43 74 78 3b 0a 20 20 7d 0a 7d 0a 0a 69 6e  teCtx;.  }.}..in
7060: 74 20 74 64 62 5f 6c 73 6d 5f 6f 70 65 6e 28 63  t tdb_lsm_open(c
7070: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 66 67 2c  onst char *zCfg,
7080: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62   const char *zDb
7090: 2c 20 69 6e 74 20 62 43 6c 65 61 72 2c 20 54 65  , int bClear, Te
70a0: 73 74 44 62 20 2a 2a 70 70 44 62 29 7b 0a 20 20  stDb **ppDb){.  
70b0: 72 65 74 75 72 6e 20 74 65 73 74 4c 73 6d 4f 70  return testLsmOp
70c0: 65 6e 28 7a 43 66 67 2c 20 7a 44 62 2c 20 62 43  en(zCfg, zDb, bC
70d0: 6c 65 61 72 2c 20 70 70 44 62 29 3b 0a 7d 0a 0a  lear, ppDb);.}..
70e0: 23 69 66 64 65 66 20 4c 53 4d 5f 4d 55 54 45 58  #ifdef LSM_MUTEX
70f0: 5f 50 54 48 52 45 41 44 53 0a 0a 2f 2a 0a 2a 2a  _PTHREADS../*.**
7100: 20 53 69 67 6e 61 6c 20 77 6f 72 6b 65 72 20 74   Signal worker t
7110: 68 72 65 61 64 20 69 57 6f 72 6b 65 72 20 74 68  hread iWorker th
7120: 61 74 20 74 68 65 72 65 20 6d 61 79 20 62 65 20  at there may be 
7130: 77 6f 72 6b 20 74 6f 20 64 6f 2e 0a 2a 2f 0a 73  work to do..*/.s
7140: 74 61 74 69 63 20 76 6f 69 64 20 6d 74 5f 73 69  tatic void mt_si
7150: 67 6e 61 6c 5f 77 6f 72 6b 65 72 28 4c 73 6d 44  gnal_worker(LsmD
7160: 62 20 2a 70 44 62 2c 20 69 6e 74 20 69 57 6f 72  b *pDb, int iWor
7170: 6b 65 72 29 7b 0a 20 20 4c 73 6d 57 6f 72 6b 65  ker){.  LsmWorke
7180: 72 20 2a 70 20 3d 20 26 70 44 62 2d 3e 61 57 6f  r *p = &pDb->aWo
7190: 72 6b 65 72 5b 69 57 6f 72 6b 65 72 5d 3b 0a 20  rker[iWorker];. 
71a0: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c   pthread_mutex_l
71b0: 6f 63 6b 28 26 70 2d 3e 77 6f 72 6b 65 72 5f 6d  ock(&p->worker_m
71c0: 75 74 65 78 29 3b 0a 20 20 70 2d 3e 62 44 6f 57  utex);.  p->bDoW
71d0: 6f 72 6b 20 3d 20 31 3b 0a 20 20 70 74 68 72 65  ork = 1;.  pthre
71e0: 61 64 5f 63 6f 6e 64 5f 73 69 67 6e 61 6c 28 26  ad_cond_signal(&
71f0: 70 2d 3e 77 6f 72 6b 65 72 5f 63 6f 6e 64 29 3b  p->worker_cond);
7200: 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78  .  pthread_mutex
7210: 5f 75 6e 6c 6f 63 6b 28 26 70 2d 3e 77 6f 72 6b  _unlock(&p->work
7220: 65 72 5f 6d 75 74 65 78 29 3b 0a 7d 0a 0a 2f 2a  er_mutex);.}../*
7230: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
7240: 20 69 73 20 75 73 65 64 20 61 73 20 74 68 65 20   is used as the 
7250: 6d 61 69 6e 28 29 20 66 6f 72 20 61 6c 6c 20 77  main() for all w
7260: 6f 72 6b 65 72 20 74 68 72 65 61 64 73 2e 0a 2a  orker threads..*
7270: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 77  /.static void *w
7280: 6f 72 6b 65 72 5f 6d 61 69 6e 28 76 6f 69 64 20  orker_main(void 
7290: 2a 70 41 72 67 29 7b 0a 20 20 4c 73 6d 57 6f 72  *pArg){.  LsmWor
72a0: 6b 65 72 20 2a 70 20 3d 20 28 4c 73 6d 57 6f 72  ker *p = (LsmWor
72b0: 6b 65 72 20 2a 29 70 41 72 67 3b 0a 20 20 6c 73  ker *)pArg;.  ls
72c0: 6d 5f 64 62 20 2a 70 57 6f 72 6b 65 72 3b 20 20  m_db *pWorker;  
72d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
72e0: 20 43 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 61   Connection to a
72f0: 63 63 65 73 73 20 64 62 20 74 68 72 6f 75 67 68  ccess db through
7300: 20 2a 2f 0a 0a 20 20 70 74 68 72 65 61 64 5f 6d   */..  pthread_m
7310: 75 74 65 78 5f 6c 6f 63 6b 28 26 70 2d 3e 77 6f  utex_lock(&p->wo
7320: 72 6b 65 72 5f 6d 75 74 65 78 29 3b 0a 20 20 77  rker_mutex);.  w
7330: 68 69 6c 65 28 20 28 70 57 6f 72 6b 65 72 20 3d  hile( (pWorker =
7340: 20 70 2d 3e 70 57 6f 72 6b 65 72 29 20 29 7b 0a   p->pWorker) ){.
7350: 20 20 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d      int rc = LSM
7360: 5f 4f 4b 3b 0a 0a 20 20 20 20 2f 2a 20 44 6f 20  _OK;..    /* Do 
7370: 73 6f 6d 65 20 77 6f 72 6b 2e 20 49 66 20 61 6e  some work. If an
7380: 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 65   error occurs, e
7390: 78 69 74 2e 20 2a 2f 0a 0a 20 20 20 20 70 74 68  xit. */..    pth
73a0: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63  read_mutex_unloc
73b0: 6b 28 26 70 2d 3e 77 6f 72 6b 65 72 5f 6d 75 74  k(&p->worker_mut
73c0: 65 78 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e  ex);.    if( p->
73d0: 65 54 79 70 65 3d 3d 4c 53 4d 54 45 53 54 5f 54  eType==LSMTEST_T
73e0: 48 52 45 41 44 5f 43 4b 50 54 20 29 7b 0a 20 20  HREAD_CKPT ){.  
73f0: 20 20 20 20 69 6e 74 20 6e 4b 42 20 3d 20 30 3b      int nKB = 0;
7400: 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 5f  .      rc = lsm_
7410: 69 6e 66 6f 28 70 57 6f 72 6b 65 72 2c 20 4c 53  info(pWorker, LS
7420: 4d 5f 49 4e 46 4f 5f 43 48 45 43 4b 50 4f 49 4e  M_INFO_CHECKPOIN
7430: 54 5f 53 49 5a 45 2c 20 26 6e 4b 42 29 3b 0a 20  T_SIZE, &nKB);. 
7440: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d       if( rc==LSM
7450: 5f 4f 4b 20 26 26 20 6e 4b 42 3e 3d 70 2d 3e 70  _OK && nKB>=p->p
7460: 44 62 2d 3e 6e 4d 74 4d 69 6e 43 6b 70 74 20 29  Db->nMtMinCkpt )
7470: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 6c  {.        rc = l
7480: 73 6d 5f 63 68 65 63 6b 70 6f 69 6e 74 28 70 57  sm_checkpoint(pW
7490: 6f 72 6b 65 72 2c 20 30 29 3b 0a 20 20 20 20 20  orker, 0);.     
74a0: 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20   }.    }else{.  
74b0: 20 20 20 20 69 6e 74 20 6e 57 72 69 74 65 3b 0a      int nWrite;.
74c0: 20 20 20 20 20 20 64 6f 20 7b 0a 0a 20 20 20 20        do {..    
74d0: 20 20 20 20 69 66 28 20 70 2d 3e 65 54 79 70 65      if( p->eType
74e0: 3d 3d 4c 53 4d 54 45 53 54 5f 54 48 52 45 41 44  ==LSMTEST_THREAD
74f0: 5f 57 4f 52 4b 45 52 20 29 7b 0a 20 20 20 20 20  _WORKER ){.     
7500: 20 20 20 20 20 77 61 69 74 4f 6e 43 68 65 63 6b       waitOnCheck
7510: 70 6f 69 6e 74 65 72 28 70 2d 3e 70 44 62 2c 20  pointer(p->pDb, 
7520: 70 57 6f 72 6b 65 72 29 3b 0a 20 20 20 20 20 20  pWorker);.      
7530: 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 6e 57 72    }..        nWr
7540: 69 74 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ite = 0;.       
7550: 20 72 63 20 3d 20 6c 73 6d 5f 77 6f 72 6b 28 70   rc = lsm_work(p
7560: 57 6f 72 6b 65 72 2c 20 30 2c 20 32 35 36 2c 20  Worker, 0, 256, 
7570: 26 6e 57 72 69 74 65 29 3b 0a 0a 20 20 20 20 20  &nWrite);..     
7580: 20 20 20 69 66 28 20 70 2d 3e 65 54 79 70 65 3d     if( p->eType=
7590: 3d 4c 53 4d 54 45 53 54 5f 54 48 52 45 41 44 5f  =LSMTEST_THREAD_
75a0: 57 4f 52 4b 45 52 20 26 26 20 6e 57 72 69 74 65  WORKER && nWrite
75b0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 74   ){.          mt
75c0: 5f 73 69 67 6e 61 6c 5f 77 6f 72 6b 65 72 28 70  _signal_worker(p
75d0: 2d 3e 70 44 62 2c 20 31 29 3b 0a 20 20 20 20 20  ->pDb, 1);.     
75e0: 20 20 20 7d 0a 20 20 20 20 20 20 7d 77 68 69 6c     }.      }whil
75f0: 65 28 20 6e 57 72 69 74 65 20 26 26 20 70 2d 3e  e( nWrite && p->
7600: 70 57 6f 72 6b 65 72 20 29 3b 0a 20 20 20 20 7d  pWorker );.    }
7610: 0a 20 20 20 20 70 74 68 72 65 61 64 5f 6d 75 74  .    pthread_mut
7620: 65 78 5f 6c 6f 63 6b 28 26 70 2d 3e 77 6f 72 6b  ex_lock(&p->work
7630: 65 72 5f 6d 75 74 65 78 29 3b 0a 0a 20 20 20 20  er_mutex);..    
7640: 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 26  if( rc!=LSM_OK &
7650: 26 20 72 63 21 3d 4c 53 4d 5f 42 55 53 59 20 29  & rc!=LSM_BUSY )
7660: 7b 0a 20 20 20 20 20 20 70 2d 3e 77 6f 72 6b 65  {.      p->worke
7670: 72 5f 72 63 20 3d 20 72 63 3b 0a 20 20 20 20 20  r_rc = rc;.     
7680: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20   break;.    }.. 
7690: 20 20 20 2f 2a 20 54 68 65 20 74 68 72 65 61 64     /* The thread
76a0: 20 77 69 6c 6c 20 77 61 6b 65 20 75 70 20 77 68   will wake up wh
76b0: 65 6e 20 69 74 20 69 73 20 73 69 67 6e 61 6c 65  en it is signale
76c0: 64 20 65 69 74 68 65 72 20 62 65 63 61 75 73 65  d either because
76d0: 20 61 6e 6f 74 68 65 72 0a 20 20 20 20 2a 2a 20   another.    ** 
76e0: 74 68 72 65 61 64 20 68 61 73 20 63 72 65 61 74  thread has creat
76f0: 65 64 20 73 6f 6d 65 20 77 6f 72 6b 20 66 6f 72  ed some work for
7700: 20 74 68 69 73 20 6f 6e 65 20 6f 72 20 62 65 63   this one or bec
7710: 61 75 73 65 20 74 68 65 20 63 6f 6e 6e 65 63 74  ause the connect
7720: 69 6f 6e 0a 20 20 20 20 2a 2a 20 69 73 20 62 65  ion.    ** is be
7730: 69 6e 67 20 63 6c 6f 73 65 64 2e 20 20 2a 2f 0a  ing closed.  */.
7740: 20 20 20 20 69 66 28 20 70 2d 3e 70 57 6f 72 6b      if( p->pWork
7750: 65 72 20 26 26 20 70 2d 3e 62 44 6f 57 6f 72 6b  er && p->bDoWork
7760: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 74 68  ==0 ){.      pth
7770: 72 65 61 64 5f 63 6f 6e 64 5f 77 61 69 74 28 26  read_cond_wait(&
7780: 70 2d 3e 77 6f 72 6b 65 72 5f 63 6f 6e 64 2c 20  p->worker_cond, 
7790: 26 70 2d 3e 77 6f 72 6b 65 72 5f 6d 75 74 65 78  &p->worker_mutex
77a0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d 3e  );.    }.    p->
77b0: 62 44 6f 57 6f 72 6b 20 3d 20 30 3b 0a 20 20 7d  bDoWork = 0;.  }
77c0: 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78  .  pthread_mutex
77d0: 5f 75 6e 6c 6f 63 6b 28 26 70 2d 3e 77 6f 72 6b  _unlock(&p->work
77e0: 65 72 5f 6d 75 74 65 78 29 3b 0a 20 20 0a 20 20  er_mutex);.  .  
77f0: 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 0a 73 74  return 0;.}...st
7800: 61 74 69 63 20 76 6f 69 64 20 6d 74 5f 73 74 6f  atic void mt_sto
7810: 70 5f 77 6f 72 6b 65 72 28 4c 73 6d 44 62 20 2a  p_worker(LsmDb *
7820: 70 44 62 2c 20 69 6e 74 20 69 57 6f 72 6b 65 72  pDb, int iWorker
7830: 29 7b 0a 20 20 4c 73 6d 57 6f 72 6b 65 72 20 2a  ){.  LsmWorker *
7840: 70 20 3d 20 26 70 44 62 2d 3e 61 57 6f 72 6b 65  p = &pDb->aWorke
7850: 72 5b 69 57 6f 72 6b 65 72 5d 3b 0a 20 20 69 66  r[iWorker];.  if
7860: 28 20 70 2d 3e 70 57 6f 72 6b 65 72 20 29 7b 0a  ( p->pWorker ){.
7870: 20 20 20 20 76 6f 69 64 20 2a 70 44 75 6d 6d 79      void *pDummy
7880: 3b 0a 20 20 20 20 6c 73 6d 5f 64 62 20 2a 70 57  ;.    lsm_db *pW
7890: 6f 72 6b 65 72 3b 0a 0a 20 20 20 20 2f 2a 20 53  orker;..    /* S
78a0: 69 67 6e 61 6c 20 74 68 65 20 77 6f 72 6b 65 72  ignal the worker
78b0: 20 74 6f 20 73 74 6f 70 20 2a 2f 0a 20 20 20 20   to stop */.    
78c0: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f  pthread_mutex_lo
78d0: 63 6b 28 26 70 2d 3e 77 6f 72 6b 65 72 5f 6d 75  ck(&p->worker_mu
78e0: 74 65 78 29 3b 0a 20 20 20 20 70 57 6f 72 6b 65  tex);.    pWorke
78f0: 72 20 3d 20 70 2d 3e 70 57 6f 72 6b 65 72 3b 0a  r = p->pWorker;.
7900: 20 20 20 20 70 2d 3e 70 57 6f 72 6b 65 72 20 3d      p->pWorker =
7910: 20 30 3b 0a 20 20 20 20 70 74 68 72 65 61 64 5f   0;.    pthread_
7920: 63 6f 6e 64 5f 73 69 67 6e 61 6c 28 26 70 2d 3e  cond_signal(&p->
7930: 77 6f 72 6b 65 72 5f 63 6f 6e 64 29 3b 0a 20 20  worker_cond);.  
7940: 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f    pthread_mutex_
7950: 75 6e 6c 6f 63 6b 28 26 70 2d 3e 77 6f 72 6b 65  unlock(&p->worke
7960: 72 5f 6d 75 74 65 78 29 3b 0a 0a 20 20 20 20 2f  r_mutex);..    /
7970: 2a 20 4a 6f 69 6e 20 74 68 65 20 77 6f 72 6b 65  * Join the worke
7980: 72 20 74 68 72 65 61 64 2e 20 2a 2f 0a 20 20 20  r thread. */.   
7990: 20 70 74 68 72 65 61 64 5f 6a 6f 69 6e 28 70 2d   pthread_join(p-
79a0: 3e 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 2c 20  >worker_thread, 
79b0: 26 70 44 75 6d 6d 79 29 3b 0a 0a 20 20 20 20 2f  &pDummy);..    /
79c0: 2a 20 46 72 65 65 20 72 65 73 6f 75 72 63 65 73  * Free resources
79d0: 20 61 6c 6c 6f 63 61 74 65 64 20 69 6e 20 6d 74   allocated in mt
79e0: 5f 73 74 61 72 74 5f 77 6f 72 6b 65 72 28 29 20  _start_worker() 
79f0: 2a 2f 0a 20 20 20 20 70 74 68 72 65 61 64 5f 63  */.    pthread_c
7a00: 6f 6e 64 5f 64 65 73 74 72 6f 79 28 26 70 2d 3e  ond_destroy(&p->
7a10: 77 6f 72 6b 65 72 5f 63 6f 6e 64 29 3b 0a 20 20  worker_cond);.  
7a20: 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f    pthread_mutex_
7a30: 64 65 73 74 72 6f 79 28 26 70 2d 3e 77 6f 72 6b  destroy(&p->work
7a40: 65 72 5f 6d 75 74 65 78 29 3b 0a 20 20 20 20 6c  er_mutex);.    l
7a50: 73 6d 5f 63 6c 6f 73 65 28 70 57 6f 72 6b 65 72  sm_close(pWorker
7a60: 29 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63  );.  }.}..static
7a70: 20 76 6f 69 64 20 6d 74 5f 73 68 75 74 64 6f 77   void mt_shutdow
7a80: 6e 28 4c 73 6d 44 62 20 2a 70 44 62 29 7b 0a 20  n(LsmDb *pDb){. 
7a90: 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d   int i;.  for(i=
7aa0: 30 3b 20 69 3c 70 44 62 2d 3e 6e 57 6f 72 6b 65  0; i<pDb->nWorke
7ab0: 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 6d 74 5f  r; i++){.    mt_
7ac0: 73 74 6f 70 5f 77 6f 72 6b 65 72 28 70 44 62 2c  stop_worker(pDb,
7ad0: 20 69 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a   i);.  }.}../*.*
7ae0: 2a 20 54 68 69 73 20 63 61 6c 6c 62 61 63 6b 20  * This callback 
7af0: 69 73 20 69 6e 76 6f 6b 65 64 20 62 79 20 4c 53  is invoked by LS
7b00: 4d 20 77 68 65 6e 20 74 68 65 20 63 6c 69 65 6e  M when the clien
7b10: 74 20 64 61 74 61 62 61 73 65 20 77 72 69 74 65  t database write
7b20: 73 20 74 6f 0a 2a 2a 20 74 68 65 20 64 61 74 61  s to.** the data
7b30: 62 61 73 65 20 66 69 6c 65 20 28 69 2e 65 2e 20  base file (i.e. 
7b40: 74 6f 20 66 6c 75 73 68 20 74 68 65 20 63 6f 6e  to flush the con
7b50: 74 65 6e 74 73 20 6f 66 20 74 68 65 20 69 6e 2d  tents of the in-
7b60: 6d 65 6d 6f 72 79 20 74 72 65 65 29 2e 0a 2a 2a  memory tree)..**
7b70: 20 54 68 69 73 20 69 6d 70 6c 69 65 73 20 74 68   This implies th
7b80: 65 72 65 20 6d 61 79 20 62 65 20 77 6f 72 6b 20  ere may be work 
7b90: 74 6f 20 64 6f 20 6f 6e 20 74 68 65 20 64 61 74  to do on the dat
7ba0: 61 62 61 73 65 2c 20 73 6f 20 73 69 67 6e 61 6c  abase, so signal
7bb0: 0a 2a 2a 20 74 68 65 20 77 6f 72 6b 65 72 20 74  .** the worker t
7bc0: 68 72 65 61 64 73 2e 0a 2a 2f 0a 73 74 61 74 69  hreads..*/.stati
7bd0: 63 20 76 6f 69 64 20 6d 74 5f 63 6c 69 65 6e 74  c void mt_client
7be0: 5f 77 6f 72 6b 5f 68 6f 6f 6b 28 6c 73 6d 5f 64  _work_hook(lsm_d
7bf0: 62 20 2a 64 62 2c 20 76 6f 69 64 20 2a 70 41 72  b *db, void *pAr
7c00: 67 29 7b 0a 20 20 4c 73 6d 44 62 20 2a 70 44 62  g){.  LsmDb *pDb
7c10: 20 3d 20 28 4c 73 6d 44 62 20 2a 29 70 41 72 67   = (LsmDb *)pArg
7c20: 3b 20 20 20 20 20 2f 2a 20 4c 73 6d 44 62 20 64  ;     /* LsmDb d
7c30: 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 2a  atabase handle *
7c40: 2f 0a 0a 20 20 2f 2a 20 49 6e 76 6f 6b 65 20 74  /..  /* Invoke t
7c50: 68 65 20 75 73 65 72 20 6c 65 76 65 6c 20 77 6f  he user level wo
7c60: 72 6b 2d 68 6f 6f 6b 2c 20 69 66 20 61 6e 79 2e  rk-hook, if any.
7c70: 20 2a 2f 0a 20 20 69 66 28 20 70 44 62 2d 3e 78   */.  if( pDb->x
7c80: 57 6f 72 6b 20 29 20 70 44 62 2d 3e 78 57 6f 72  Work ) pDb->xWor
7c90: 6b 28 64 62 2c 20 70 44 62 2d 3e 70 57 6f 72 6b  k(db, pDb->pWork
7ca0: 43 74 78 29 3b 0a 0a 20 20 2f 2a 20 57 61 6b 65  Ctx);..  /* Wake
7cb0: 20 75 70 20 77 6f 72 6b 65 72 20 74 68 72 65 61   up worker threa
7cc0: 64 20 30 2e 20 2a 2f 0a 20 20 6d 74 5f 73 69 67  d 0. */.  mt_sig
7cd0: 6e 61 6c 5f 77 6f 72 6b 65 72 28 70 44 62 2c 20  nal_worker(pDb, 
7ce0: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  0);.}..static vo
7cf0: 69 64 20 6d 74 5f 77 6f 72 6b 65 72 5f 77 6f 72  id mt_worker_wor
7d00: 6b 5f 68 6f 6f 6b 28 6c 73 6d 5f 64 62 20 2a 64  k_hook(lsm_db *d
7d10: 62 2c 20 76 6f 69 64 20 2a 70 41 72 67 29 7b 0a  b, void *pArg){.
7d20: 20 20 4c 73 6d 44 62 20 2a 70 44 62 20 3d 20 28    LsmDb *pDb = (
7d30: 4c 73 6d 44 62 20 2a 29 70 41 72 67 3b 20 20 20  LsmDb *)pArg;   
7d40: 20 20 2f 2a 20 4c 73 6d 44 62 20 64 61 74 61 62    /* LsmDb datab
7d50: 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 0a 20  ase handle */.. 
7d60: 20 2f 2a 20 49 6e 76 6f 6b 65 20 74 68 65 20 75   /* Invoke the u
7d70: 73 65 72 20 6c 65 76 65 6c 20 77 6f 72 6b 2d 68  ser level work-h
7d80: 6f 6f 6b 2c 20 69 66 20 61 6e 79 2e 20 2a 2f 0a  ook, if any. */.
7d90: 20 20 69 66 28 20 70 44 62 2d 3e 78 57 6f 72 6b    if( pDb->xWork
7da0: 20 29 20 70 44 62 2d 3e 78 57 6f 72 6b 28 64 62   ) pDb->xWork(db
7db0: 2c 20 70 44 62 2d 3e 70 57 6f 72 6b 43 74 78 29  , pDb->pWorkCtx)
7dc0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 61 75 6e 63  ;.}../*.** Launc
7dd0: 68 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 20  h worker thread 
7de0: 69 57 6f 72 6b 65 72 20 66 6f 72 20 64 61 74 61  iWorker for data
7df0: 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  base connection 
7e00: 70 44 62 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  pDb..*/.static i
7e10: 6e 74 20 6d 74 5f 73 74 61 72 74 5f 77 6f 72 6b  nt mt_start_work
7e20: 65 72 28 0a 20 20 4c 73 6d 44 62 20 2a 70 44 62  er(.  LsmDb *pDb
7e30: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
7e40: 20 20 20 20 20 20 2f 2a 20 4d 61 69 6e 20 64 61        /* Main da
7e50: 74 61 62 61 73 65 20 73 74 72 75 63 74 75 72 65  tabase structure
7e60: 20 2a 2f 0a 20 20 69 6e 74 20 69 57 6f 72 6b 65   */.  int iWorke
7e70: 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r,              
7e80: 20 20 20 20 20 20 2f 2a 20 57 6f 72 6b 65 72 20        /* Worker 
7e90: 6e 75 6d 62 65 72 20 74 6f 20 73 74 61 72 74 20  number to start 
7ea0: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
7eb0: 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 20 20 20 20  *zFilename,     
7ec0: 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 6e 61 6d       /* File nam
7ed0: 65 20 6f 66 20 64 61 74 61 62 61 73 65 20 74 6f  e of database to
7ee0: 20 6f 70 65 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74   open */.  const
7ef0: 20 63 68 61 72 20 2a 7a 43 66 67 2c 20 20 20 20   char *zCfg,    
7f00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
7f10: 6e 6e 65 63 74 69 6f 6e 20 63 6f 6e 66 69 67 75  nnection configu
7f20: 72 61 74 69 6f 6e 20 73 74 72 69 6e 67 20 2a 2f  ration string */
7f30: 0a 20 20 69 6e 74 20 65 54 79 70 65 20 20 20 20  .  int eType    
7f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7f50: 20 20 20 2f 2a 20 54 79 70 65 20 6f 66 20 77 6f     /* Type of wo
7f60: 72 6b 65 72 20 74 68 72 65 61 64 20 2a 2f 0a 29  rker thread */.)
7f70: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 30 3b 20  {.  int rc = 0; 
7f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7f90: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
7fa0: 64 65 20 2a 2f 0a 20 20 4c 73 6d 57 6f 72 6b 65  de */.  LsmWorke
7fb0: 72 20 2a 70 3b 20 20 20 20 20 20 20 20 20 20 20  r *p;           
7fc0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63          /* Objec
7fd0: 74 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20  t to initialize 
7fe0: 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 69 57  */..  assert( iW
7ff0: 6f 72 6b 65 72 3c 70 44 62 2d 3e 6e 57 6f 72 6b  orker<pDb->nWork
8000: 65 72 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  er );.  assert( 
8010: 65 54 79 70 65 3d 3d 4c 53 4d 54 45 53 54 5f 54  eType==LSMTEST_T
8020: 48 52 45 41 44 5f 43 4b 50 54 20 0a 20 20 20 20  HREAD_CKPT .    
8030: 20 20 20 7c 7c 20 65 54 79 70 65 3d 3d 4c 53 4d     || eType==LSM
8040: 54 45 53 54 5f 54 48 52 45 41 44 5f 57 4f 52 4b  TEST_THREAD_WORK
8050: 45 52 20 0a 20 20 20 20 20 20 20 7c 7c 20 65 54  ER .       || eT
8060: 79 70 65 3d 3d 4c 53 4d 54 45 53 54 5f 54 48 52  ype==LSMTEST_THR
8070: 45 41 44 5f 57 4f 52 4b 45 52 5f 41 43 20 0a 20  EAD_WORKER_AC . 
8080: 20 29 3b 0a 0a 20 20 70 20 3d 20 26 70 44 62 2d   );..  p = &pDb-
8090: 3e 61 57 6f 72 6b 65 72 5b 69 57 6f 72 6b 65 72  >aWorker[iWorker
80a0: 5d 3b 0a 20 20 70 2d 3e 65 54 79 70 65 20 3d 20  ];.  p->eType = 
80b0: 65 54 79 70 65 3b 0a 20 20 70 2d 3e 70 44 62 20  eType;.  p->pDb 
80c0: 3d 20 70 44 62 3b 0a 0a 20 20 2f 2a 20 4f 70 65  = pDb;..  /* Ope
80d0: 6e 20 74 68 65 20 77 6f 72 6b 65 72 20 63 6f 6e  n the worker con
80e0: 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 66 28  nection */.  if(
80f0: 20 72 63 3d 3d 30 20 29 20 72 63 20 3d 20 6c 73   rc==0 ) rc = ls
8100: 6d 5f 6e 65 77 28 26 70 44 62 2d 3e 65 6e 76 2c  m_new(&pDb->env,
8110: 20 26 70 2d 3e 70 57 6f 72 6b 65 72 29 3b 0a 20   &p->pWorker);. 
8120: 20 69 66 28 20 7a 43 66 67 20 29 7b 0a 20 20 20   if( zCfg ){.   
8130: 20 74 65 73 74 5f 6c 73 6d 5f 63 6f 6e 66 69 67   test_lsm_config
8140: 5f 73 74 72 28 70 44 62 2c 20 70 2d 3e 70 57 6f  _str(pDb, p->pWo
8150: 72 6b 65 72 2c 20 31 2c 20 7a 43 66 67 2c 20 30  rker, 1, zCfg, 0
8160: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d  );.  }.  if( rc=
8170: 3d 30 20 29 20 72 63 20 3d 20 6c 73 6d 5f 6f 70  =0 ) rc = lsm_op
8180: 65 6e 28 70 2d 3e 70 57 6f 72 6b 65 72 2c 20 7a  en(p->pWorker, z
8190: 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 6c 73 6d  Filename);.  lsm
81a0: 5f 63 6f 6e 66 69 67 5f 6c 6f 67 28 70 2d 3e 70  _config_log(p->p
81b0: 57 6f 72 6b 65 72 2c 20 78 4c 6f 67 2c 20 28 76  Worker, xLog, (v
81c0: 6f 69 64 20 2a 29 22 77 6f 72 6b 65 72 22 29 3b  oid *)"worker");
81d0: 0a 0a 20 20 2f 2a 20 43 6f 6e 66 69 67 75 72 65  ..  /* Configure
81e0: 20 74 68 65 20 77 6f 72 6b 2d 68 6f 6f 6b 20 2a   the work-hook *
81f0: 2f 0a 20 20 69 66 28 20 72 63 3d 3d 30 20 29 7b  /.  if( rc==0 ){
8200: 0a 20 20 20 20 6c 73 6d 5f 63 6f 6e 66 69 67 5f  .    lsm_config_
8210: 77 6f 72 6b 5f 68 6f 6f 6b 28 70 2d 3e 70 57 6f  work_hook(p->pWo
8220: 72 6b 65 72 2c 20 6d 74 5f 77 6f 72 6b 65 72 5f  rker, mt_worker_
8230: 77 6f 72 6b 5f 68 6f 6f 6b 2c 20 28 76 6f 69 64  work_hook, (void
8240: 20 2a 29 70 44 62 29 3b 0a 20 20 7d 0a 0a 20 20   *)pDb);.  }..  
8250: 69 66 28 20 65 54 79 70 65 3d 3d 4c 53 4d 54 45  if( eType==LSMTE
8260: 53 54 5f 54 48 52 45 41 44 5f 57 4f 52 4b 45 52  ST_THREAD_WORKER
8270: 20 29 7b 0a 20 20 20 20 74 65 73 74 5f 6c 73 6d   ){.    test_lsm
8280: 5f 63 6f 6e 66 69 67 5f 73 74 72 28 30 2c 20 70  _config_str(0, p
8290: 2d 3e 70 57 6f 72 6b 65 72 2c 20 31 2c 20 22 61  ->pWorker, 1, "a
82a0: 75 74 6f 63 68 65 63 6b 70 6f 69 6e 74 3d 30 22  utocheckpoint=0"
82b0: 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  , 0);.  }..  /* 
82c0: 4b 69 63 6b 20 6f 66 66 20 74 68 65 20 77 6f 72  Kick off the wor
82d0: 6b 65 72 20 74 68 72 65 61 64 2e 20 2a 2f 0a 20  ker thread. */. 
82e0: 20 69 66 28 20 72 63 3d 3d 30 20 29 20 72 63 20   if( rc==0 ) rc 
82f0: 3d 20 70 74 68 72 65 61 64 5f 63 6f 6e 64 5f 69  = pthread_cond_i
8300: 6e 69 74 28 26 70 2d 3e 77 6f 72 6b 65 72 5f 63  nit(&p->worker_c
8310: 6f 6e 64 2c 20 30 29 3b 0a 20 20 69 66 28 20 72  ond, 0);.  if( r
8320: 63 3d 3d 30 20 29 20 72 63 20 3d 20 70 74 68 72  c==0 ) rc = pthr
8330: 65 61 64 5f 6d 75 74 65 78 5f 69 6e 69 74 28 26  ead_mutex_init(&
8340: 70 2d 3e 77 6f 72 6b 65 72 5f 6d 75 74 65 78 2c  p->worker_mutex,
8350: 20 30 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 30   0);.  if( rc==0
8360: 20 29 20 72 63 20 3d 20 70 74 68 72 65 61 64 5f   ) rc = pthread_
8370: 63 72 65 61 74 65 28 26 70 2d 3e 77 6f 72 6b 65  create(&p->worke
8380: 72 5f 74 68 72 65 61 64 2c 20 30 2c 20 77 6f 72  r_thread, 0, wor
8390: 6b 65 72 5f 6d 61 69 6e 2c 20 28 76 6f 69 64 20  ker_main, (void 
83a0: 2a 29 70 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20  *)p);..  return 
83b0: 72 63 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69  rc;.}...static i
83c0: 6e 74 20 74 65 73 74 4c 73 6d 53 74 61 72 74 57  nt testLsmStartW
83d0: 6f 72 6b 65 72 73 28 0a 20 20 4c 73 6d 44 62 20  orkers(.  LsmDb 
83e0: 2a 70 44 62 2c 20 69 6e 74 20 65 4d 6f 64 65 6c  *pDb, int eModel
83f0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46  , const char *zF
8400: 69 6c 65 6e 61 6d 65 2c 20 63 6f 6e 73 74 20 63  ilename, const c
8410: 68 61 72 20 2a 7a 43 66 67 0a 29 7b 0a 20 20 69  har *zCfg.){.  i
8420: 6e 74 20 72 63 3b 0a 0a 20 20 69 66 28 20 65 4d  nt rc;..  if( eM
8430: 6f 64 65 6c 3c 31 20 7c 7c 20 65 4d 6f 64 65 6c  odel<1 || eModel
8440: 3e 34 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20  >4 ) return 1;. 
8450: 20 69 66 28 20 65 4d 6f 64 65 6c 3d 3d 31 20 29   if( eModel==1 )
8460: 20 72 65 74 75 72 6e 20 30 3b 0a 0a 20 20 2f 2a   return 0;..  /*
8470: 20 43 6f 6e 66 69 67 75 72 65 20 61 20 77 6f 72   Configure a wor
8480: 6b 2d 68 6f 6f 6b 20 66 6f 72 20 74 68 65 20 63  k-hook for the c
8490: 6c 69 65 6e 74 20 63 6f 6e 6e 65 63 74 69 6f 6e  lient connection
84a0: 2e 20 57 6f 72 6b 65 72 20 30 20 69 73 20 73 69  . Worker 0 is si
84b0: 67 6e 61 6c 6c 65 64 0a 20 20 2a 2a 20 65 76 65  gnalled.  ** eve
84c0: 72 79 20 74 69 6d 65 20 74 68 65 20 75 73 65 72  ry time the user
84d0: 73 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 77 72 69  s connection wri
84e0: 74 65 73 20 74 6f 20 74 68 65 20 64 61 74 61 62  tes to the datab
84f0: 61 73 65 2e 20 20 2a 2f 0a 20 20 6c 73 6d 5f 63  ase.  */.  lsm_c
8500: 6f 6e 66 69 67 5f 77 6f 72 6b 5f 68 6f 6f 6b 28  onfig_work_hook(
8510: 70 44 62 2d 3e 64 62 2c 20 6d 74 5f 63 6c 69 65  pDb->db, mt_clie
8520: 6e 74 5f 77 6f 72 6b 5f 68 6f 6f 6b 2c 20 28 76  nt_work_hook, (v
8530: 6f 69 64 20 2a 29 70 44 62 29 3b 0a 0a 20 20 2f  oid *)pDb);..  /
8540: 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70 61 63 65  * Allocate space
8550: 20 66 6f 72 20 74 77 6f 20 77 6f 72 6b 65 72 20   for two worker 
8560: 63 6f 6e 6e 65 63 74 69 6f 6e 73 2e 20 54 68 65  connections. The
8570: 79 20 6d 61 79 20 6e 6f 74 20 62 6f 74 68 20 62  y may not both b
8580: 65 0a 20 20 2a 2a 20 75 73 65 64 2c 20 62 75 74  e.  ** used, but
8590: 20 62 6f 74 68 20 61 72 65 20 61 6c 6c 6f 63 61   both are alloca
85a0: 74 65 64 2e 20 20 2a 2f 0a 20 20 70 44 62 2d 3e  ted.  */.  pDb->
85b0: 61 57 6f 72 6b 65 72 20 3d 20 28 4c 73 6d 57 6f  aWorker = (LsmWo
85c0: 72 6b 65 72 20 2a 29 74 65 73 74 4d 61 6c 6c 6f  rker *)testMallo
85d0: 63 28 73 69 7a 65 6f 66 28 4c 73 6d 57 6f 72 6b  c(sizeof(LsmWork
85e0: 65 72 29 20 2a 20 32 29 3b 0a 20 20 6d 65 6d 73  er) * 2);.  mems
85f0: 65 74 28 70 44 62 2d 3e 61 57 6f 72 6b 65 72 2c  et(pDb->aWorker,
8600: 20 30 2c 20 73 69 7a 65 6f 66 28 4c 73 6d 57 6f   0, sizeof(LsmWo
8610: 72 6b 65 72 29 20 2a 20 32 29 3b 0a 0a 20 20 73  rker) * 2);..  s
8620: 77 69 74 63 68 28 20 65 4d 6f 64 65 6c 20 29 7b  witch( eModel ){
8630: 0a 20 20 20 20 63 61 73 65 20 4c 53 4d 54 45 53  .    case LSMTES
8640: 54 5f 4d 4f 44 45 5f 42 41 43 4b 47 52 4f 55 4e  T_MODE_BACKGROUN
8650: 44 5f 43 4b 50 54 3a 0a 20 20 20 20 20 20 70 44  D_CKPT:.      pD
8660: 62 2d 3e 6e 57 6f 72 6b 65 72 20 3d 20 31 3b 0a  b->nWorker = 1;.
8670: 20 20 20 20 20 20 74 65 73 74 5f 6c 73 6d 5f 63        test_lsm_c
8680: 6f 6e 66 69 67 5f 73 74 72 28 30 2c 20 70 44 62  onfig_str(0, pDb
8690: 2d 3e 64 62 2c 20 30 2c 20 22 61 75 74 6f 63 68  ->db, 0, "autoch
86a0: 65 63 6b 70 6f 69 6e 74 3d 30 22 2c 20 30 29 3b  eckpoint=0", 0);
86b0: 0a 20 20 20 20 20 20 72 63 20 3d 20 6d 74 5f 73  .      rc = mt_s
86c0: 74 61 72 74 5f 77 6f 72 6b 65 72 28 70 44 62 2c  tart_worker(pDb,
86d0: 20 30 2c 20 7a 46 69 6c 65 6e 61 6d 65 2c 20 7a   0, zFilename, z
86e0: 43 66 67 2c 20 4c 53 4d 54 45 53 54 5f 54 48 52  Cfg, LSMTEST_THR
86f0: 45 41 44 5f 43 4b 50 54 29 3b 0a 20 20 20 20 20  EAD_CKPT);.     
8700: 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73   break;..    cas
8710: 65 20 4c 53 4d 54 45 53 54 5f 4d 4f 44 45 5f 42  e LSMTEST_MODE_B
8720: 41 43 4b 47 52 4f 55 4e 44 5f 57 4f 52 4b 3a 0a  ACKGROUND_WORK:.
8730: 20 20 20 20 20 20 70 44 62 2d 3e 6e 57 6f 72 6b        pDb->nWork
8740: 65 72 20 3d 20 31 3b 0a 20 20 20 20 20 20 74 65  er = 1;.      te
8750: 73 74 5f 6c 73 6d 5f 63 6f 6e 66 69 67 5f 73 74  st_lsm_config_st
8760: 72 28 30 2c 20 70 44 62 2d 3e 64 62 2c 20 30 2c  r(0, pDb->db, 0,
8770: 20 22 61 75 74 6f 77 6f 72 6b 3d 30 22 2c 20 30   "autowork=0", 0
8780: 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 6d 74  );.      rc = mt
8790: 5f 73 74 61 72 74 5f 77 6f 72 6b 65 72 28 70 44  _start_worker(pD
87a0: 62 2c 20 30 2c 20 7a 46 69 6c 65 6e 61 6d 65 2c  b, 0, zFilename,
87b0: 20 7a 43 66 67 2c 20 4c 53 4d 54 45 53 54 5f 54   zCfg, LSMTEST_T
87c0: 48 52 45 41 44 5f 57 4f 52 4b 45 52 5f 41 43 29  HREAD_WORKER_AC)
87d0: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a  ;.      break;..
87e0: 20 20 20 20 63 61 73 65 20 4c 53 4d 54 45 53 54      case LSMTEST
87f0: 5f 4d 4f 44 45 5f 42 41 43 4b 47 52 4f 55 4e 44  _MODE_BACKGROUND
8800: 5f 42 4f 54 48 3a 0a 20 20 20 20 20 20 70 44 62  _BOTH:.      pDb
8810: 2d 3e 6e 57 6f 72 6b 65 72 20 3d 20 32 3b 0a 20  ->nWorker = 2;. 
8820: 20 20 20 20 20 74 65 73 74 5f 6c 73 6d 5f 63 6f       test_lsm_co
8830: 6e 66 69 67 5f 73 74 72 28 30 2c 20 70 44 62 2d  nfig_str(0, pDb-
8840: 3e 64 62 2c 20 30 2c 20 22 61 75 74 6f 77 6f 72  >db, 0, "autowor
8850: 6b 3d 30 22 2c 20 30 29 3b 0a 20 20 20 20 20 20  k=0", 0);.      
8860: 72 63 20 3d 20 6d 74 5f 73 74 61 72 74 5f 77 6f  rc = mt_start_wo
8870: 72 6b 65 72 28 70 44 62 2c 20 30 2c 20 7a 46 69  rker(pDb, 0, zFi
8880: 6c 65 6e 61 6d 65 2c 20 7a 43 66 67 2c 20 4c 53  lename, zCfg, LS
8890: 4d 54 45 53 54 5f 54 48 52 45 41 44 5f 57 4f 52  MTEST_THREAD_WOR
88a0: 4b 45 52 29 3b 0a 20 20 20 20 20 20 69 66 28 20  KER);.      if( 
88b0: 72 63 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  rc==0 ){.       
88c0: 20 72 63 20 3d 20 6d 74 5f 73 74 61 72 74 5f 77   rc = mt_start_w
88d0: 6f 72 6b 65 72 28 70 44 62 2c 20 31 2c 20 7a 46  orker(pDb, 1, zF
88e0: 69 6c 65 6e 61 6d 65 2c 20 7a 43 66 67 2c 20 4c  ilename, zCfg, L
88f0: 53 4d 54 45 53 54 5f 54 48 52 45 41 44 5f 43 4b  SMTEST_THREAD_CK
8900: 50 54 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  PT);.      }.   
8910: 20 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20     break;.  }.. 
8920: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a   return rc;.}...
8930: 69 6e 74 20 74 65 73 74 5f 6c 73 6d 5f 6d 74 32  int test_lsm_mt2
8940: 28 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  (.  const char *
8950: 7a 53 70 65 63 2c 20 0a 20 20 63 6f 6e 73 74 20  zSpec, .  const 
8960: 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 2c  char *zFilename,
8970: 20 0a 20 20 69 6e 74 20 62 43 6c 65 61 72 2c 20   .  int bClear, 
8980: 0a 20 20 54 65 73 74 44 62 20 2a 2a 70 70 44 62  .  TestDb **ppDb
8990: 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  .){.  const char
89a0: 20 2a 7a 43 66 67 20 3d 20 22 6d 74 5f 6d 6f 64   *zCfg = "mt_mod
89b0: 65 3d 32 22 3b 0a 20 20 72 65 74 75 72 6e 20 74  e=2";.  return t
89c0: 65 73 74 4c 73 6d 4f 70 65 6e 28 7a 43 66 67 2c  estLsmOpen(zCfg,
89d0: 20 7a 46 69 6c 65 6e 61 6d 65 2c 20 62 43 6c 65   zFilename, bCle
89e0: 61 72 2c 20 70 70 44 62 29 3b 0a 7d 0a 0a 69 6e  ar, ppDb);.}..in
89f0: 74 20 74 65 73 74 5f 6c 73 6d 5f 6d 74 33 28 0a  t test_lsm_mt3(.
8a00: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53    const char *zS
8a10: 70 65 63 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68  pec, .  const ch
8a20: 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 0a  ar *zFilename, .
8a30: 20 20 69 6e 74 20 62 43 6c 65 61 72 2c 20 0a 20    int bClear, . 
8a40: 20 54 65 73 74 44 62 20 2a 2a 70 70 44 62 0a 29   TestDb **ppDb.)
8a50: 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  {.  const char *
8a60: 7a 43 66 67 20 3d 20 22 6d 74 5f 6d 6f 64 65 3d  zCfg = "mt_mode=
8a70: 34 22 3b 0a 20 20 72 65 74 75 72 6e 20 74 65 73  4";.  return tes
8a80: 74 4c 73 6d 4f 70 65 6e 28 7a 43 66 67 2c 20 7a  tLsmOpen(zCfg, z
8a90: 46 69 6c 65 6e 61 6d 65 2c 20 62 43 6c 65 61 72  Filename, bClear
8aa0: 2c 20 70 70 44 62 29 3b 0a 7d 0a 0a 23 65 6c 73  , ppDb);.}..#els
8ab0: 65 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 74  e.static void mt
8ac0: 5f 73 68 75 74 64 6f 77 6e 28 4c 73 6d 44 62 20  _shutdown(LsmDb 
8ad0: 2a 70 44 62 29 20 7b 20 0a 20 20 75 6e 75 73 65  *pDb) { .  unuse
8ae0: 64 5f 70 61 72 61 6d 65 74 65 72 28 70 44 62 29  d_parameter(pDb)
8af0: 3b 20 0a 7d 0a 69 6e 74 20 74 65 73 74 5f 6c 73  ; .}.int test_ls
8b00: 6d 5f 6d 74 28 63 6f 6e 73 74 20 63 68 61 72 20  m_mt(const char 
8b10: 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 69 6e 74 20  *zFilename, int 
8b20: 62 43 6c 65 61 72 2c 20 54 65 73 74 44 62 20 2a  bClear, TestDb *
8b30: 2a 70 70 44 62 29 7b 0a 20 20 75 6e 75 73 65 64  *ppDb){.  unused
8b40: 5f 70 61 72 61 6d 65 74 65 72 28 7a 46 69 6c 65  _parameter(zFile
8b50: 6e 61 6d 65 29 3b 0a 20 20 75 6e 75 73 65 64 5f  name);.  unused_
8b60: 70 61 72 61 6d 65 74 65 72 28 62 43 6c 65 61 72  parameter(bClear
8b70: 29 3b 0a 20 20 75 6e 75 73 65 64 5f 70 61 72 61  );.  unused_para
8b80: 6d 65 74 65 72 28 70 70 44 62 29 3b 0a 20 20 74  meter(ppDb);.  t
8b90: 65 73 74 50 72 69 6e 74 45 72 72 6f 72 28 22 74  estPrintError("t
8ba0: 68 72 65 61 64 73 20 75 6e 61 76 61 69 6c 61 62  hreads unavailab
8bb0: 6c 65 20 2d 20 72 65 63 6f 6d 70 69 6c 65 20 77  le - recompile w
8bc0: 69 74 68 20 4c 53 4d 5f 4d 55 54 45 58 5f 50 54  ith LSM_MUTEX_PT
8bd0: 48 52 45 41 44 53 5c 6e 22 29 3b 0a 20 20 72 65  HREADS\n");.  re
8be0: 74 75 72 6e 20 31 3b 0a 7d 0a 23 65 6e 64 69 66  turn 1;.}.#endif
8bf0: 0a                                               .