@ -26,14 +26,11 @@ unsigned int nWalletDBUpdated;
// CDB
//
CCriticalSection cs_db ;
static bool fDbEnvInit = false ;
bool fDetachDB = false ;
DbEnv dbenv ( 0 ) ;
CDBEnv bitdb ;
map < string , int > mapFileUseCount ;
static map < string , Db * > mapDb ;
static void EnvShutdown ( )
void CDBEnv : : EnvShutdown ( )
{
if ( ! fDbEnvInit )
return ;
@ -50,18 +47,67 @@ static void EnvShutdown()
DbEnv ( 0 ) . remove ( GetDataDir ( ) . string ( ) . c_str ( ) , 0 ) ;
}
class CDBInit
CDBEnv : : CDBEnv ( ) : dbenv ( 0 )
{
public :
CDBInit ( )
{
}
~ CDBInit ( )
{
EnvShutdown ( ) ;
}
}
instance_of_cdbinit ;
CDBEnv : : ~ CDBEnv ( )
{
EnvShutdown ( ) ;
}
void CDBEnv : : Close ( )
{
EnvShutdown ( ) ;
}
bool CDBEnv : : Open ( boost : : filesystem : : path pathEnv_ )
{
if ( fDbEnvInit )
return true ;
if ( fShutdown )
return false ;
pathEnv = pathEnv_ ;
filesystem : : path pathDataDir = pathEnv ;
filesystem : : path pathLogDir = pathDataDir / " database " ;
filesystem : : create_directory ( pathLogDir ) ;
filesystem : : path pathErrorFile = pathDataDir / " db.log " ;
printf ( " dbenv.open LogDir=%s ErrorFile=%s \n " , pathLogDir . string ( ) . c_str ( ) , pathErrorFile . string ( ) . c_str ( ) ) ;
int nDbCache = GetArg ( " -dbcache " , 25 ) ;
dbenv . set_lg_dir ( pathLogDir . string ( ) . c_str ( ) ) ;
dbenv . set_cachesize ( nDbCache / 1024 , ( nDbCache % 1024 ) * 1048576 , 1 ) ;
dbenv . set_lg_bsize ( 1048576 ) ;
dbenv . set_lg_max ( 10485760 ) ;
dbenv . set_lk_max_locks ( 10000 ) ;
dbenv . set_lk_max_objects ( 10000 ) ;
dbenv . set_errfile ( fopen ( pathErrorFile . string ( ) . c_str ( ) , " a " ) ) ; /// debug
dbenv . set_flags ( DB_AUTO_COMMIT , 1 ) ;
dbenv . set_flags ( DB_TXN_WRITE_NOSYNC , 1 ) ;
dbenv . log_set_config ( DB_LOG_AUTO_REMOVE , 1 ) ;
int ret = dbenv . open ( pathDataDir . string ( ) . c_str ( ) ,
DB_CREATE |
DB_INIT_LOCK |
DB_INIT_LOG |
DB_INIT_MPOOL |
DB_INIT_TXN |
DB_THREAD |
DB_RECOVER ,
S_IRUSR | S_IWUSR ) ;
if ( ret > 0 )
return error ( " CDB() : error % d opening database environment " , ret) ;
fDbEnvInit = true ;
return true ;
}
void CDBEnv : : CheckpointLSN ( std : : string strFile )
{
dbenv . txn_checkpoint ( 0 , 0 , 0 ) ;
dbenv . lsn_reset ( strFile . c_str ( ) , 0 ) ;
}
CDB : : CDB ( const char * pszFile , const char * pszMode ) : pdb ( NULL )
@ -77,48 +123,16 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL)
nFlags | = DB_CREATE ;
{
LOCK ( cs_db ) ;
if ( ! fDbEnvInit )
{
if ( fShutdown )
return ;
filesystem : : path pathDataDir = GetDataDir ( ) ;
filesystem : : path pathLogDir = pathDataDir / " database " ;
filesystem : : create_directory ( pathLogDir ) ;
filesystem : : path pathErrorFile = pathDataDir / " db.log " ;
printf ( " dbenv.open LogDir=%s ErrorFile=%s \n " , pathLogDir . string ( ) . c_str ( ) , pathErrorFile . string ( ) . c_str ( ) ) ;
int nDbCache = GetArg ( " -dbcache " , 25 ) ;
dbenv . set_lg_dir ( pathLogDir . string ( ) . c_str ( ) ) ;
dbenv . set_cachesize ( nDbCache / 1024 , ( nDbCache % 1024 ) * 1048576 , 1 ) ;
dbenv . set_lg_bsize ( 1048576 ) ;
dbenv . set_lg_max ( 10485760 ) ;
dbenv . set_lk_max_locks ( 10000 ) ;
dbenv . set_lk_max_objects ( 10000 ) ;
dbenv . set_errfile ( fopen ( pathErrorFile . string ( ) . c_str ( ) , " a " ) ) ; /// debug
dbenv . set_flags ( DB_TXN_WRITE_NOSYNC , 1 ) ;
dbenv . set_flags ( DB_AUTO_COMMIT , 1 ) ;
dbenv . log_set_config ( DB_LOG_AUTO_REMOVE , 1 ) ;
ret = dbenv . open ( pathDataDir . string ( ) . c_str ( ) ,
DB_CREATE |
DB_INIT_LOCK |
DB_INIT_LOG |
DB_INIT_MPOOL |
DB_INIT_TXN |
DB_THREAD |
DB_RECOVER ,
S_IRUSR | S_IWUSR ) ;
if ( ret > 0 )
throw runtime_error ( strprintf ( " CDB() : error % d opening database environment " , ret)) ;
fDbEnvInit = true ;
}
LOCK ( bitdb . cs_db ) ;
if ( ! bitdb . Open ( GetDataDir ( ) ) )
throw runtime_error ( " env open failed " ) ;
strFile = pszFile ;
+ + mapFileUseCount [ strFile ] ;
pdb = mapDb [ strFile ] ;
if ( pdb = = NULL )
{
pdb = new Db ( & dbenv, 0 ) ;
pdb = new Db ( & bitdb . dbenv , 0 ) ;
ret = pdb - > open ( NULL , // Txn pointer
pszFile , // Filename
@ -132,7 +146,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL)
delete pdb ;
pdb = NULL ;
{
LOCK ( cs_db) ;
LOCK ( bitdb. cs_db) ;
- - mapFileUseCount [ strFile ] ;
}
strFile = " " ;
@ -170,10 +184,10 @@ void CDB::Close()
if ( strFile = = " blkindex.dat " & & IsInitialBlockDownload ( ) )
nMinutes = 5 ;
dbenv. txn_checkpoint ( nMinutes ? GetArg ( " -dblogsize " , 100 ) * 1024 : 0 , nMinutes , 0 ) ;
bitdb. dbenv. txn_checkpoint ( nMinutes ? GetArg ( " -dblogsize " , 100 ) * 1024 : 0 , nMinutes , 0 ) ;
{
LOCK ( cs_db) ;
LOCK ( bitdb. cs_db) ;
- - mapFileUseCount [ strFile ] ;
}
}
@ -181,7 +195,7 @@ void CDB::Close()
void CloseDb ( const string & strFile )
{
{
LOCK ( cs_db) ;
LOCK ( bitdb. cs_db) ;
if ( mapDb [ strFile ] ! = NULL )
{
// Close the database handle
@ -198,13 +212,12 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
while ( ! fShutdown )
{
{
LOCK ( cs_db) ;
LOCK ( bitdb. cs_db) ;
if ( ! mapFileUseCount . count ( strFile ) | | mapFileUseCount [ strFile ] = = 0 )
{
// Flush log data to the dat file
CloseDb ( strFile ) ;
dbenv . txn_checkpoint ( 0 , 0 , 0 ) ;
dbenv . lsn_reset ( strFile . c_str ( ) , 0 ) ;
bitdb . CheckpointLSN ( strFile ) ;
mapFileUseCount . erase ( strFile ) ;
bool fSuccess = true ;
@ -212,7 +225,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
string strFileRes = strFile + " .rewrite " ;
{ // surround usage of db with extra {}
CDB db ( strFile . c_str ( ) , " r " ) ;
Db * pdbCopy = new Db ( & dbenv, 0 ) ;
Db * pdbCopy = new Db ( & bitdb. dbenv, 0 ) ;
int ret = pdbCopy - > open ( NULL , // Txn pointer
strFileRes . c_str ( ) , // Filename
@ -270,10 +283,10 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
}
if ( fSuccess )
{
Db dbA ( & dbenv, 0 ) ;
Db dbA ( & bitdb. dbenv, 0 ) ;
if ( dbA . remove ( strFile . c_str ( ) , NULL , 0 ) )
fSuccess = false ;
Db dbB ( & dbenv, 0 ) ;
Db dbB ( & bitdb. dbenv, 0 ) ;
if ( dbB . rename ( strFileRes . c_str ( ) , NULL , strFile . c_str ( ) , 0 ) )
fSuccess = false ;
}
@ -288,12 +301,12 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
}
void DBFlush( bool fShutdown )
void C DBEnv: : Flush( bool fShutdown )
{
int64 nStart = GetTimeMillis ( ) ;
// Flush log data to the actual data file
// on all files that are not in use
printf ( " DB Flush(%s)%s\n " , fShutdown ? " true " : " false " , fDbEnvInit ? " " : " db not started " ) ;
printf ( " Flush(%s)%s\n " , fShutdown ? " true " : " false " , fDbEnvInit ? " " : " db not started " ) ;
if ( ! fDbEnvInit )
return ;
{
@ -327,7 +340,7 @@ void DBFlush(bool fShutdown)
if ( mapFileUseCount . empty ( ) )
{
dbenv . log_archive ( & listp , DB_ARCH_REMOVE ) ;
EnvShutdown ( ) ;
Close ( ) ;
}
}
}