Index: lsm-test/lsmtest_func.c ================================================================== --- lsm-test/lsmtest_func.c +++ lsm-test/lsmtest_func.c @@ -5,20 +5,20 @@ int do_work(int nArg, char **azArg){ struct Option { const char *zName; } aOpt [] = { { "-nmerge" }, - { "-npage" }, + { "-nkb" }, { 0 } }; lsm_db *pDb; int rc; int i; const char *zDb; int nMerge = 1; - int nWork = (1<<30); + int nKB = (1<<30); if( nArg==0 ) goto usage; zDb = azArg[nArg-1]; for(i=0; i<(nArg-1); i++){ int iSel; @@ -31,11 +31,11 @@ nMerge = atoi(azArg[i]); break; case 1: i++; if( i==(nArg-1) ) goto usage; - nWork = atoi(azArg[i]); + nKB = atoi(azArg[i]); break; } } rc = lsm_new(0, &pDb); @@ -49,11 +49,11 @@ int n = -1; lsm_config(pDb, LSM_CONFIG_BLOCK_SIZE, &n); n = n*2; lsm_config(pDb, LSM_CONFIG_AUTOCHECKPOINT, &n); - rc = lsm_work(pDb, nMerge, nWork, 0); + rc = lsm_work(pDb, nMerge, nKB, 0); if( rc!=LSM_OK ){ testPrintError("lsm_work(): rc=%d\n", rc); } } } Index: src/lsm.h ================================================================== --- src/lsm.h +++ src/lsm.h @@ -489,11 +489,11 @@ /* ** CAPI: Explicit Database Work and Checkpointing ** ** This function is called by a thread to work on the database structure. */ -int lsm_work(lsm_db *pDb, int nMerge, int nPage, int *pnWrite); +int lsm_work(lsm_db *pDb, int nMerge, int nKB, int *pnWrite); int lsm_flush(lsm_db *pDb); /* ** Attempt to checkpoint the current database snapshot. Return an LSM Index: src/lsm_sorted.c ================================================================== --- src/lsm_sorted.c +++ src/lsm_sorted.c @@ -5198,21 +5198,23 @@ int rc = LSM_OK; /* Return code */ int nWrite = 0; /* Number of pages written */ assert( nMerge>=1 ); - if( nPage>0 ){ + if( nPage!=0 ){ int bCkpt = 0; do { int nThis = 0; + int nReq = (nPage>=0) ? (nPage-nWrite) : ((int)0x7FFFFFFF); + bCkpt = 0; - rc = doLsmSingleWork(pDb, 0, nMerge, nPage-nWrite, &nThis, &bCkpt); + rc = doLsmSingleWork(pDb, 0, nMerge, nReq, &nThis, &bCkpt); nWrite += nThis; if( rc==LSM_OK && bCkpt ){ rc = lsm_checkpoint(pDb, 0); } - }while( rc==LSM_OK && (nWritenTransOpen || pDb->pCsr ) return LSM_MISUSE_BKPT; - if( nMerge<=0 ) nMerge = pDb->nMerge; - return doLsmWork(pDb, nMerge, nPage, pnWrite); + + /* Convert from KB to pages */ + nPgsz = lsmFsPageSize(pDb->pFS); + if( nKB>=0 ){ + nPage = ((i64)nKB * 1024 + nPgsz - 1) / nPgsz; + }else{ + nPage = -1; + } + + rc = doLsmWork(pDb, nMerge, nPage, &nWrite); + + if( pnWrite ){ + /* Convert back from pages to KB */ + *pnWrite = (int)(((i64)nWrite * 1024 + nPgsz - 1) / nPgsz); + } + return rc; } int lsm_flush(lsm_db *db){ int rc; @@ -5299,10 +5319,11 @@ nRemaining = nUnit * nDepth; #ifdef LSM_LOG_WORK lsmLogMessage(pDb, rc, "lsmSortedAutoWork(): %d*%d = %d pages", nUnit, nDepth, nRemaining); #endif + assert( nRemaining>=0 ); rc = doLsmWork(pDb, pDb->nMerge, nRemaining, 0); if( rc==LSM_BUSY ) rc = LSM_OK; if( bRestore && pDb->pCsr ){ lsmFreeSnapshot(pDb->pEnv, pDb->pClient); Index: tool/lsmview.tcl ================================================================== --- tool/lsmview.tcl +++ tool/lsmview.tcl @@ -399,11 +399,11 @@ $myText delete 0.0 end # Delete the existing tree entries. $myTree delete [$myTree children {}] - set nBlksz [exec_lsmtest_show -c $myCfg $myDb blocksize] + set nBlksz [expr [exec_lsmtest_show -c $myCfg $myDb blocksize] * 1024] set nPgsz [exec_lsmtest_show -c $myCfg $myDb pagesize] if {[regexp {c=1} $myCfg] || [regexp {co=1} $myCfg] || [regexp {com=1} $myCfg] || [regexp {comp=1} $myCfg] || [regexp {compr=1} $myCfg] || [regexp {compres=1} $myCfg] Index: www/lsmusr.wiki ================================================================== --- www/lsmusr.wiki +++ www/lsmusr.wiki @@ -1287,11 +1287,11 @@ the following are true:

In order to optimize the database, lsm_work() should be called with the nMerge argument set to 1 and the third parameter set to a negative value -(interpreted as - keep working until there is no more work to do). For +(interpreted as "keep working until there is no more work to do"). For example: rc = lsm_work(db, 1, -1, 0); -

todo: the -1 as the 3rd argument above is currently -not supported -

When optimizing the database as above, either the LSM_CONFIG_AUTOCHECKPOINT parameter should be set to a non-zero value or lsm_checkpoint() should be called periodically. Otherwise, no checkpoints will be performed, preventing the library from reusing any space occupied by old segments even after their content has been merged into the new segment. The result - a database file that is optimized, except that it is up to twice as large as it otherwise would be. -