Index: lsm-test/lsmtest_main.c ================================================================== --- lsm-test/lsmtest_main.c +++ lsm-test/lsmtest_main.c @@ -1331,29 +1331,33 @@ return rc; } static int do_insert(int nArg, char **azArg){ - const char *zConfig = 0; const char *zDb = "lsm"; TestDb *pDb = 0; int i; int rc; const int nRow = 1 * 1000 * 1000; DatasourceDefn defn = { TEST_DATASOURCE_RANDOM, 8, 15, 80, 150 }; Datasource *pData = 0; - if( nArg>2 ){ - testPrintError("Usage: insert ?DATABASE? ?LSM-CONFIG?\n"); + if( nArg>1 ){ + testPrintError("Usage: insert ?DATABASE?\n"); return 1; } if( nArg==1 ){ zDb = azArg[0]; } - if( nArg==2 ){ zConfig = azArg[1]; } testMallocUninstall(tdb_lsm_env()); - rc = tdb_open(zDb, 0, 1, &pDb); + for(i=0; zDb[i] && zDb[i]!='='; i++); + if( zDb[i] ){ + rc = tdb_lsm_open(zDb, "testdb.lsm", 1, &pDb); + }else{ + rc = tdb_open(zDb, 0, 1, &pDb); + } + if( rc!=0 ){ testPrintError("Error opening db \"%s\": %d\n", zDb, rc); }else{ InsertWriteHook hook; memset(&hook, 0, sizeof(hook)); @@ -1360,13 +1364,10 @@ hook.pOut = fopen("writelog.txt", "w"); pData = testDatasourceNew(&defn); tdb_lsm_config_work_hook(pDb, do_insert_work_hook, 0); tdb_lsm_write_hook(pDb, do_insert_write_hook, (void *)&hook); - if( zConfig ){ - rc = tdb_lsm_config_str(pDb, zConfig); - } if( rc==0 ){ for(i=0; i> 14); +** aHdr[1] = 0x80 | (u8)(nSz >> 7); +** aHdr[2] = 0x80 | (u8)(nSz >> 0); ** ** * Compressed page image. ** -** * The number of bytes in the compressed page image, again as a 3-byte -** big-endian integer. +** * A second copy of the 3-byte record header. ** ** A page number is a byte offset into the database file. So the smallest ** possible page number is 8192 (immediately after the two meta-pages). ** The first and root page of a segment are identified by a page number ** corresponding to the byte offset of the first byte in the corresponding @@ -115,22 +127,21 @@ ** page record. The last page of a segment is identified by the byte offset ** of the last byte in its record. ** ** Unlike uncompressed pages, compressed page records may span blocks. ** -** TODO: -** ** Sometimes, in order to avoid touching sectors that contain synced data ** when writing, it is necessary to insert unused space between compressed ** page records. This can be done as follows: ** -** * For less than 4 bytes of empty space, a series of 0x00 bytes. +** * For less than 6 bytes of empty space, a series of 0x00 bytes. ** -** * For 4 or more bytes, the block of free space begins with an -** 0x01 byte, followed by a varint containing the total size of the -** free space. Similarly, it ends with an (ABCD -> BCDA) transformed -** varint an a final 0x01 byte. +** * For 6 or more bytes of empty space, a record similar to a +** compressed page record is added to the segment. A padding record +** is distinguished from a compressed page record by the most +** significant bit of the second byte of the size field, which is +** cleared instead of set. */ #include "lsmInt.h" #include #include @@ -933,19 +944,24 @@ } return rc; } /* -** Encode and decode routines for 24-bit big-endian integers. -*/ -static u32 lsmGetU24(u8 *aBuf){ - return (((u32)aBuf[0]) << 16) + (((u32)aBuf[1]) << 8) + ((u32)aBuf[2]); -} -static void lsmPutU24(u8 *aBuf, u32 iVal){ - aBuf[0] = (u8)(iVal >> 16); - aBuf[1] = (u8)(iVal >> 8); - aBuf[2] = (u8)(iVal >> 0); +** Encode and decode routines for record size fields. +*/ +static void putRecordSize(u8 *aBuf, int nByte, int bFree){ + aBuf[0] = (u8)(nByte >> 14) | 0x80; + aBuf[1] = ((u8)(nByte >> 7) & 0x7F) | (bFree ? 0x00 : 0x80); + aBuf[2] = (u8)nByte | 0x80; +} +static int getRecordSize(u8 *aBuf, int *pbFree){ + int nByte; + nByte = (aBuf[0] & 0x7F) << 14; + nByte += (aBuf[1] & 0x7F) << 7; + nByte += (aBuf[2] & 0x7F); + *pbFree = !!(aBuf[1] & 0x80); + return nByte; } static int fsSubtractOffset(FileSystem *pFS, i64 iOff, int iSub, i64 *piRes){ i64 iStart; int iBlk; @@ -1013,11 +1029,12 @@ if( fsAllocateBuffer(pFS) ) return LSM_NOMEM; rc = fsReadData(pFS, iOff, aSz, sizeof(aSz)); if( rc==LSM_OK ){ - pPg->nCompress = (int)lsmGetU24(aSz); + int bFree; + pPg->nCompress = (int)getRecordSize(aSz, &bFree); rc = fsAddOffset(pFS, iOff, 3, &iOff); if( rc==LSM_OK ){ if( pPg->nCompress>pFS->nBuffer ){ rc = LSM_CORRUPT_BKPT; }else{ @@ -1319,12 +1336,13 @@ i64 iRead; rc = fsSubtractOffset(pFS, iOff, sizeof(aSz), &iRead); if( rc==LSM_OK ) rc = fsReadData(pFS, iRead, aSz, sizeof(aSz)); if( rc==LSM_OK ){ - int nSz = lsmGetU24(aSz) + sizeof(aSz)*2; - rc = fsSubtractOffset(pFS, iOff, nSz, piPrev); + int bFree; + int nSz = getRecordSize(aSz, &bFree); + rc = fsSubtractOffset(pFS, iOff, nSz + sizeof(aSz)*2, piPrev); } return rc; } @@ -1770,11 +1788,11 @@ /* Compress the page image. */ rc = fsCompressIntoBuffer(pFS, pPg); /* Serialize the compressed size into buffer aSz[] */ - lsmPutU24(aSz, pPg->nCompress); + putRecordSize(aSz, pPg->nCompress, 0); /* Write the serialized page record into the database file. */ pPg->iPg = fsAppendData(pFS, pPg->pSeg, aSz, sizeof(aSz), &rc); fsAppendData(pFS, pPg->pSeg, pFS->aBuffer, pPg->nCompress, &rc); fsAppendData(pFS, pPg->pSeg, aSz, sizeof(aSz), &rc);