Index: src/lsm_file.c ================================================================== --- src/lsm_file.c +++ src/lsm_file.c @@ -551,49 +551,51 @@ ** Configure the file-system object according to the current values of ** the LSM_CONFIG_MMAP and LSM_CONFIG_SET_COMPRESSION options. */ int lsmFsConfigure(lsm_db *db){ FileSystem *pFS = db->pFS; - lsm_env *pEnv = pFS->pEnv; - Page *pPg; - - assert( pFS->nOut==0 ); - assert( pFS->pWaiting==0 ); - - /* Reset any compression/decompression buffers already allocated */ - lsmFree(pEnv, pFS->aIBuffer); - lsmFree(pEnv, pFS->aOBuffer); - pFS->nBuffer = 0; - - /* Unmap the file, if it is currently mapped */ - if( pFS->pMap ){ - lsmEnvRemap(pEnv, pFS->fdDb, -1, &pFS->pMap, &pFS->nMap); - pFS->bUseMmap = 0; - } - - /* Free all allocate page structures */ - pPg = pFS->pLruFirst; - while( pPg ){ - Page *pNext = pPg->pLruNext; - if( pPg->flags & PAGE_FREE ) lsmFree(pEnv, pPg->aData); - lsmFree(pEnv, pPg); - pPg = pNext; - } - - /* Zero pointers that point to deleted page objects */ - pFS->nCacheAlloc = 0; - pFS->pLruFirst = 0; - pFS->pLruLast = 0; - pFS->pFree = 0; - - /* Configure the FileSystem object */ - if( db->compress.xCompress ){ - pFS->pCompress = &db->compress; - pFS->bUseMmap = 0; - }else{ - pFS->pCompress = 0; - pFS->bUseMmap = db->bMmap; + if( pFS ){ + lsm_env *pEnv = pFS->pEnv; + Page *pPg; + + assert( pFS->nOut==0 ); + assert( pFS->pWaiting==0 ); + + /* Reset any compression/decompression buffers already allocated */ + lsmFree(pEnv, pFS->aIBuffer); + lsmFree(pEnv, pFS->aOBuffer); + pFS->nBuffer = 0; + + /* Unmap the file, if it is currently mapped */ + if( pFS->pMap ){ + lsmEnvRemap(pEnv, pFS->fdDb, -1, &pFS->pMap, &pFS->nMap); + pFS->bUseMmap = 0; + } + + /* Free all allocate page structures */ + pPg = pFS->pLruFirst; + while( pPg ){ + Page *pNext = pPg->pLruNext; + if( pPg->flags & PAGE_FREE ) lsmFree(pEnv, pPg->aData); + lsmFree(pEnv, pPg); + pPg = pNext; + } + + /* Zero pointers that point to deleted page objects */ + pFS->nCacheAlloc = 0; + pFS->pLruFirst = 0; + pFS->pLruLast = 0; + pFS->pFree = 0; + + /* Configure the FileSystem object */ + if( db->compress.xCompress ){ + pFS->pCompress = &db->compress; + pFS->bUseMmap = 0; + }else{ + pFS->pCompress = 0; + pFS->bUseMmap = db->bMmap; + } } return LSM_OK; } Index: src/lsm_main.c ================================================================== --- src/lsm_main.c +++ src/lsm_main.c @@ -295,12 +295,13 @@ break; } case LSM_CONFIG_MMAP: { int *piVal = va_arg(ap, int *); - if( pDb->pDatabase==0 ){ - pDb->bMmap = (LSM_IS_64_BIT && *piVal); + if( pDb->iReader<0 && *piVal>=0 && *piVal<=1 ){ + pDb->bMmap = *piVal; + rc = lsmFsConfigure(pDb); } *piVal = pDb->bMmap; break; } Index: src/lsm_unix.c ================================================================== --- src/lsm_unix.c +++ src/lsm_unix.c @@ -121,15 +121,19 @@ static int lsmPosixOsTruncate( lsm_file *pFile, /* File to write to */ lsm_i64 nSize /* Size to truncate file to */ ){ - int rc = LSM_OK; + PosixFile *p = (PosixFile *)pFile; + int rc = LSM_OK; /* Return code */ int prc; /* Posix Return Code */ - PosixFile *p = (PosixFile *)pFile; - - prc = ftruncate(p->fd, (off_t)nSize); + struct stat sStat; /* Result of fstat() invocation */ + + prc = fstat(p->fd, &sStat); + if( prc==0 && sStat.st_size>nSize ){ + prc = ftruncate(p->fd, (off_t)nSize); + } if( prc<0 ) rc = lsm_ioerr(); return rc; } Index: test/lsm4.test ================================================================== --- test/lsm4.test +++ test/lsm4.test @@ -6,10 +6,14 @@ # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** +# +# The focus of this file is testing the LSM library. More specifically, +# it focuses on testing the compression, compression-id and +# compression-factory functionality. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix lsm4 ADDED test/lsm5.test Index: test/lsm5.test ================================================================== --- /dev/null +++ test/lsm5.test @@ -0,0 +1,42 @@ +# 2013 February 08 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# The focus of this file is testing the LSM library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix lsm5 +db close + +#------------------------------------------------------------------------- +# When the database system is shut down (i.e. when the last connection +# disconnects), an attempt is made to truncate the database file to the +# minimum number of blocks required. +# +# This test case checks that this process does not actually cause the +# database to grow. +# +do_test 1.1 { + lsm_open db test.db + db config {mmap 0} +} {0} +do_test 1.2 { + db write 1 one + db write 2 two + db close +} {} +do_test 1.3 { + expr [file size test.db] < (64*1024) +} 1 + +finish_test + Index: www/lsmusr.wiki ================================================================== --- www/lsmusr.wiki +++ www/lsmusr.wiki @@ -1015,12 +1015,12 @@ it is false, data is accessed using ordinary OS file read and write primitives. Memory mapping the database file can significantly improve the performance of read operations, as database pages do not have to be copied from operating system buffers into user space buffers before they can be examined. -

This option can only be set before lsm_open() is called on the database - connection. +

This option may not be set if there is a read or write transaction + open on the database.

The default value is 1 (true) on a 64-bit platform, and 0 otherwise.

LSM_CONFIG_MULTIPLE_PROCESSES

This option may also be set to either 1 (true) or 0 (false). The default