Index: src/lsmInt.h ================================================================== --- src/lsmInt.h +++ src/lsmInt.h @@ -729,11 +729,11 @@ void lsmLogEnd(lsm_db *pDb, int bCommit); void lsmLogTell(lsm_db *, LogMark *); void lsmLogSeek(lsm_db *, LogMark *); int lsmLogRecover(lsm_db *); -int lsmLogStructure(lsm_db *pDb, char **pzVal); +int lsmInfoLogStructure(lsm_db *pDb, char **pzVal); /************************************************************************** ** Functions from file "lsm_shared.c". */ Index: src/lsm_log.c ================================================================== --- src/lsm_log.c +++ src/lsm_log.c @@ -742,21 +742,40 @@ if( pMark->iOff > pLog->iRegion1End ) pLog->iRegion1End = 0; if( pMark->iOff > pLog->iRegion2Start ) pLog->iRegion2Start = 0; } /* -** TODO: Thread safety of this function? +** This function does the work for an lsm_info(LOG_STRUCTURE) request. */ -int lsmLogStructure(lsm_db *pDb, char **pzVal){ - DbLog *pLog = &pDb->treehdr.log; - *pzVal = lsmMallocPrintf(pDb->pEnv, - "%d %d %d %d %d %d", - (int)pLog->aRegion[0].iStart, (int)pLog->aRegion[0].iEnd, - (int)pLog->aRegion[1].iStart, (int)pLog->aRegion[1].iEnd, - (int)pLog->aRegion[2].iStart, (int)pLog->aRegion[2].iEnd - ); - return (*pzVal ? LSM_OK : LSM_NOMEM_BKPT); +int lsmInfoLogStructure(lsm_db *pDb, char **pzVal){ + int rc = LSM_OK; + char *zVal = 0; + + /* If there is no read or write transaction open, read the latest + ** tree-header from shared-memory to report on. If necessary, update + ** it based on the contents of the database header. + ** + ** No locks are taken here - these are passive read operations only. + */ + if( pDb->pCsr==0 && pDb->nTransOpen==0 ){ + rc = lsmTreeLoadHeader(pDb, 0); + if( rc==LSM_OK ) rc = logReclaimSpace(pDb); + } + + if( rc==LSM_OK ){ + DbLog *pLog = &pDb->treehdr.log; + zVal = lsmMallocPrintf(pDb->pEnv, + "%d %d %d %d %d %d", + (int)pLog->aRegion[0].iStart, (int)pLog->aRegion[0].iEnd, + (int)pLog->aRegion[1].iStart, (int)pLog->aRegion[1].iEnd, + (int)pLog->aRegion[2].iStart, (int)pLog->aRegion[2].iEnd + ); + if( !zVal ) rc = LSM_NOMEM_BKPT; + } + + *pzVal = zVal; + return rc; } /************************************************************************* ** Begin code for log recovery. */ Index: src/lsm_main.c ================================================================== --- src/lsm_main.c +++ src/lsm_main.c @@ -479,11 +479,11 @@ break; } case LSM_INFO_LOG_STRUCTURE: { char **pzVal = va_arg(ap, char **); - rc = lsmLogStructure(pDb, pzVal); + rc = lsmInfoLogStructure(pDb, pzVal); break; } default: rc = LSM_MISUSE; Index: test/log2.test ================================================================== --- test/log2.test +++ test/log2.test @@ -102,11 +102,11 @@ execsql { INSERT INTO t1 VALUES(randstr(10,10), randstr(100, 100)) } execsql COMMIT } {} do_test 3.11 { sqlite4_lsm_info db main log-structure -} {1124 1271 0 1062 1272 1809} +} {0 0 139 1062 1272 1809} do_recover_test 3.12 { SELECT * FROM t1 } [execsql {SELECT * FROM t1}] #------------------------------------------------------------------------- # reset_db