Index: ext/lsm1/lsm-test/lsmtest1.c ================================================================== --- ext/lsm1/lsm-test/lsmtest1.c +++ ext/lsm1/lsm-test/lsmtest1.c @@ -79,16 +79,16 @@ /* ** Generate a unique name for the test case pTest with database system ** zSystem. */ -static char *getName(const char *zSystem, Datatest1 *pTest){ +static char *getName(const char *zSystem, int bRecover, Datatest1 *pTest){ char *zRet; char *zData; zData = testDatasourceName(&pTest->defn); - zRet = testMallocPrintf("data.%s.%s.%d.%d", - zSystem, zData, pTest->nRow, pTest->nVerify + zRet = testMallocPrintf("data.%s.%s.rec=%d.%d.%d", + zSystem, zData, bRecover, pTest->nRow, pTest->nVerify ); testFree(zData); return zRet; } @@ -248,13 +248,26 @@ ){ printf("%s\n", (char *)pKey); fflush(stdout); } #endif + +void testReopenRecover(TestDb **ppDb, int *pRc){ + if( *pRc==0 ){ + const char *zLib = tdb_library_name(*ppDb); + const char *zDflt = tdb_default_db(zLib); + testCopyLsmdb(zDflt, "bak.db"); + testClose(ppDb); + testCopyLsmdb("bak.db", zDflt); + *pRc = tdb_open(zLib, 0, 0, ppDb); + } +} + static void doDataTest1( const char *zSystem, /* Database system to test */ + int bRecover, Datatest1 *p, /* Structure containing test parameters */ int *pRc /* OUT: Error code */ ){ int i; int iDot; @@ -275,12 +288,15 @@ i += p->nVerify; /* Check that the db content is correct. */ testDbContents(pDb, pData, p->nRow, 0, i-1, p->nTest, p->bTestScan, &rc); - /* Close and reopen the database. */ - testReopen(&pDb, &rc); + if( bRecover ){ + testReopenRecover(&pDb, &rc); + }else{ + testReopen(&pDb, &rc); + } /* Check that the db content is still correct. */ testDbContents(pDb, pData, p->nRow, 0, i-1, p->nTest, p->bTestScan, &rc); /* Update the progress dots... */ @@ -297,11 +313,15 @@ /* Check that the db content is correct. */ testDbContents(pDb, pData, p->nRow, i, p->nRow-1,p->nTest,p->bTestScan,&rc); /* Close and reopen the database. */ - testReopen(&pDb, &rc); + if( bRecover ){ + testReopenRecover(&pDb, &rc); + }else{ + testReopen(&pDb, &rc); + } /* Check that the db content is still correct. */ testDbContents(pDb, pData, p->nRow, i, p->nRow-1,p->nTest,p->bTestScan,&rc); /* Update the progress dots... */ @@ -337,17 +357,21 @@ { {DATA_RANDOM, 10,10, 100,100}, 100000, 1000, 100, 0}, { {DATA_SEQUENTIAL, 10,10, 100,100}, 100000, 1000, 100, 0}, }; int i; + int bRecover; - for(i=0; *pRc==LSM_OK && inIter, testCaseNDot(), &iDot); } @@ -449,16 +478,16 @@ testDatasourceFree(pData); testCaseFinish(rc); *pRc = rc; } -static char *getName2(const char *zSystem, Datatest2 *pTest){ +static char *getName2(const char *zSystem, int bRecover, Datatest2 *pTest){ char *zRet; char *zData; zData = testDatasourceName(&pTest->defn); - zRet = testMallocPrintf("data2.%s.%s.%d.%d.%d", - zSystem, zData, pTest->nRange, pTest->nWrite, pTest->nIter + zRet = testMallocPrintf("data2.%s.%s.rec=%d.%d.%d.%d", + zSystem, zData, bRecover, pTest->nRange, pTest->nWrite, pTest->nIter ); testFree(zData); return zRet; } @@ -474,17 +503,21 @@ { {DATA_RANDOM, 20,25, 100,200}, 100, 10, 1000 }, { {DATA_RANDOM, 20,25, 100,200}, 100, 200, 50 }, }; int i; + int bRecover; - for(i=0; *pRc==LSM_OK && i=ArraySize(aLib) ) return 0; return aLib[i].zName; } + +const char *tdb_default_db(const char *zSys){ + int i; + for(i=0; i=0) or LSM_LOG_DELETE (if nVal<0) ** record to the database log. */ int lsmLogWrite( lsm_db *pDb, /* Database handle */ + int eType, void *pKey, int nKey, /* Database key to write to log */ void *pVal, int nVal /* Database value (or nVal<0) to write */ ){ int rc = LSM_OK; LogWriter *pLog; /* Log object to write to */ int nReq; /* Bytes of space required in log */ int bCksum = 0; /* True to embed a checksum in this record */ + assert( eType==LSM_WRITE || eType==LSM_DELETE || eType==LSM_DRANGE ); + assert( LSM_LOG_WRITE==LSM_WRITE ); + assert( LSM_LOG_DELETE==LSM_DELETE ); + assert( LSM_LOG_DRANGE==LSM_DRANGE ); + assert( (eType==LSM_LOG_DELETE)==(nVal<0) ); + if( pDb->bUseLog==0 ) return LSM_OK; pLog = pDb->pLogWriter; /* Determine how many bytes of space are required, assuming that a checksum ** will be embedded in this record (even though it may not be). */ nReq = 1 + lsmVarintLen32(nKey) + 8 + nKey; - if( nVal>=0 ) nReq += lsmVarintLen32(nVal) + nVal; + if( eType!=LSM_LOG_DELETE ) nReq += lsmVarintLen32(nVal) + nVal; /* Jump over the jump region if required. Set bCksum to true to tell the ** code below to include a checksum in the record if either (a) writing ** this record would mean that more than LSM_CKSUM_MAXDATA bytes of data ** have been written to the log since the last checksum, or (b) the jump @@ -685,23 +696,24 @@ /* Write the record header - the type byte followed by either 1 (for ** DELETE) or 2 (for WRITE) varints. */ assert( LSM_LOG_WRITE_CKSUM == (LSM_LOG_WRITE | 0x0001) ); assert( LSM_LOG_DELETE_CKSUM == (LSM_LOG_DELETE | 0x0001) ); - *(a++) = (nVal>=0 ? LSM_LOG_WRITE : LSM_LOG_DELETE) | (u8)bCksum; + assert( LSM_LOG_DRANGE_CKSUM == (LSM_LOG_DRANGE | 0x0001) ); + *(a++) = (u8)eType | (u8)bCksum; a += lsmVarintPut32(a, nKey); - if( nVal>=0 ) a += lsmVarintPut32(a, nVal); + if( eType!=LSM_LOG_DELETE ) a += lsmVarintPut32(a, nVal); if( bCksum ){ pLog->buf.n = (a - (u8 *)pLog->buf.z); rc = logCksumAndFlush(pDb); a = (u8 *)&pLog->buf.z[pLog->buf.n]; } memcpy(a, pKey, nKey); a += nKey; - if( nVal>=0 ){ + if( eType!=LSM_LOG_DELETE ){ memcpy(a, pVal, nVal); a += nVal; } pLog->buf.n = a - (u8 *)pLog->buf.z; assert( pLog->buf.n<=pLog->buf.nAlloc ); @@ -1003,29 +1015,35 @@ logReaderVarint(&reader, &buf1, &nPad, &rc); logReaderBlob(&reader, &buf1, nPad, 0, &rc); break; } + case LSM_LOG_DRANGE: + case LSM_LOG_DRANGE_CKSUM: case LSM_LOG_WRITE: case LSM_LOG_WRITE_CKSUM: { int nKey; int nVal; u8 *aVal; logReaderVarint(&reader, &buf1, &nKey, &rc); logReaderVarint(&reader, &buf2, &nVal, &rc); - if( eType==LSM_LOG_WRITE_CKSUM ){ + if( eType==LSM_LOG_WRITE_CKSUM || eType==LSM_LOG_DRANGE_CKSUM ){ logReaderCksum(&reader, &buf1, &bEof, &rc); }else{ bEof = logRequireCksum(&reader, nKey+nVal); } if( bEof ) break; logReaderBlob(&reader, &buf1, nKey, 0, &rc); logReaderBlob(&reader, &buf2, nVal, &aVal, &rc); if( iPass==1 && rc==LSM_OK ){ - rc = lsmTreeInsert(pDb, (u8 *)buf1.z, nKey, aVal, nVal); + if( eType==LSM_LOG_WRITE || eType==LSM_LOG_WRITE_CKSUM ){ + rc = lsmTreeInsert(pDb, (u8 *)buf1.z, nKey, aVal, nVal); + }else{ + rc = lsmTreeDelete(pDb, (u8 *)buf1.z, nKey, aVal, nVal); + } } break; } case LSM_LOG_DELETE: Index: ext/lsm1/lsm_main.c ================================================================== --- ext/lsm1/lsm_main.c +++ ext/lsm1/lsm_main.c @@ -667,15 +667,12 @@ bCommit = 1; rc = lsm_begin(pDb, 1); } if( rc==LSM_OK ){ - if( bDeleteRange==0 ){ - rc = lsmLogWrite(pDb, (void *)pKey, nKey, (void *)pVal, nVal); - }else{ - /* TODO */ - } + int eType = (bDeleteRange ? LSM_DRANGE : (nVal>=0?LSM_WRITE:LSM_DELETE)); + rc = lsmLogWrite(pDb, eType, (void *)pKey, nKey, (void *)pVal, nVal); } lsmSortedSaveTreeCursors(pDb); if( rc==LSM_OK ){