@ -182,18 +182,39 @@ void DBDumper::DoCommand() {
const char * ReduceDBLevels : : NEW_LEVLES_ARG = " --new_levels= " ;
const char * ReduceDBLevels : : PRINT_OLD_LEVELS_ARG = " --print_old_levels " ;
const char * ReduceDBLevels : : COMPRESSION_TYPE_ARG = " --compression= " ;
const char * ReduceDBLevels : : FILE_SIZE_ARG = " --file_size= " ;
ReduceDBLevels : : ReduceDBLevels ( std : : string & db_name ,
std : : vector < std : : string > & args )
: LDBCommand ( db_name , args ) ,
old_levels_ ( 1 < < 16 ) ,
new_levels_ ( - 1 ) ,
print_old_levels_ ( false ) {
file_size_ = leveldb : : Options ( ) . target_file_size_base ;
compression_ = leveldb : : Options ( ) . compression ;
for ( unsigned int i = 0 ; i < args . size ( ) ; i + + ) {
std : : string & arg = args . at ( i ) ;
if ( arg . find ( NEW_LEVLES_ARG ) = = 0 ) {
new_levels_ = atoi ( arg . substr ( strlen ( NEW_LEVLES_ARG ) ) . c_str ( ) ) ;
} else if ( arg . find ( PRINT_OLD_LEVELS_ARG ) = = 0 ) {
print_old_levels_ = true ;
} else if ( arg . find ( COMPRESSION_TYPE_ARG ) = = 0 ) {
const char * type = arg . substr ( strlen ( COMPRESSION_TYPE_ARG ) ) . c_str ( ) ;
if ( ! strcasecmp ( type , " none " ) )
compression_ = leveldb : : kNoCompression ;
else if ( ! strcasecmp ( type , " snappy " ) )
compression_ = leveldb : : kSnappyCompression ;
else if ( ! strcasecmp ( type , " zlib " ) )
compression_ = leveldb : : kZlibCompression ;
else if ( ! strcasecmp ( type , " bzip2 " ) )
compression_ = leveldb : : kBZip2Compression ;
else
exec_state_ = LDBCommandExecuteResult : : FAILED (
" Invalid compression arg : " + arg ) ;
} else if ( arg . find ( FILE_SIZE_ARG ) = = 0 ) {
file_size_ = atoi ( arg . substr ( strlen ( FILE_SIZE_ARG ) ) . c_str ( ) ) ;
} else {
exec_state_ = LDBCommandExecuteResult : : FAILED (
" Unknown argument. " + arg ) ;
@ -223,15 +244,45 @@ void ReduceDBLevels::Help(std::string& msg) {
LDBCommand : : Help ( msg ) ;
msg . append ( " [--new_levels=New number of levels] " ) ;
msg . append ( " [--print_old_levels] " ) ;
msg . append ( " [--compression=none|snappy|zlib|bzip2] " ) ;
msg . append ( " [--file_size= per-file size] " ) ;
}
leveldb : : Options ReduceDBLevels : : PrepareOptionsForOpenDB ( ) {
leveldb : : Options opt = LDBCommand : : PrepareOptionsForOpenDB ( ) ;
// Set to a big value to make sure we can open the db
opt . num_levels = 1 < < 16 ;
opt . num_levels = old_levels_ ;
// Disable size compaction
opt . max_bytes_for_level_base = 1 < < 60 ;
opt . max_bytes_for_level_multiplier = 1 ;
opt . max_mem_compaction_level = 0 ;
return opt ;
}
Status ReduceDBLevels : : GetOldNumOfLevels ( leveldb : : Options & opt , int * levels ) {
TableCache * tc = new TableCache ( db_path_ , & opt , 10 ) ;
const InternalKeyComparator * cmp = new InternalKeyComparator (
opt . comparator ) ;
VersionSet * versions = new VersionSet ( db_path_ , & opt ,
tc , cmp ) ;
// We rely the VersionSet::Recover to tell us the internal data structures
// in the db. And the Recover() should never do any change
// (like LogAndApply) to the manifest file.
Status st = versions - > Recover ( ) ;
if ( ! st . ok ( ) ) {
return st ;
}
int max = - 1 ;
for ( int i = 0 ; i < versions - > NumberLevels ( ) ; i + + ) {
if ( versions - > NumLevelFiles ( i ) ) {
max = i ;
}
}
* levels = max + 1 ;
delete versions ;
return st ;
}
void ReduceDBLevels : : DoCommand ( ) {
if ( new_levels_ < = 1 ) {
exec_state_ = LDBCommandExecuteResult : : FAILED (
@ -240,34 +291,27 @@ void ReduceDBLevels::DoCommand() {
}
leveldb : : Status st ;
leveldb : : Options opt = PrepareOptionsForOpenDB ( ) ;
int old_level_num = - 1 ;
st = GetOldNumOfLevels ( opt , & old_level_num ) ;
if ( ! st . ok ( ) ) {
exec_state_ = LDBCommandExecuteResult : : FAILED ( st . ToString ( ) ) ;
return ;
}
if ( print_old_levels_ ) {
TableCache * tc = new TableCache ( db_path_ , & opt , 10 ) ;
const InternalKeyComparator * cmp = new InternalKeyComparator (
opt . comparator ) ;
VersionSet * versions = new VersionSet ( db_path_ , & opt ,
tc , cmp ) ;
// We rely the VersionSet::Recover to tell us the internal data structures
// in the db. And the Recover() should never do any change
// (like LogAndApply) to the manifest file.
st = versions - > Recover ( ) ;
int max = - 1 ;
for ( int i = 0 ; i < versions - > NumberLevels ( ) ; i + + ) {
if ( versions - > NumLevelFiles ( i ) ) {
max = i ;
}
}
fprintf ( stdout , " The old number of levels in use is %d \n " , max + 1 ) ;
delete versions ;
fprintf ( stdout , " The old number of levels in use is %d \n " , old_level_num ) ;
}
if ( ! st . ok ( ) ) {
exec_state_ = LDBCommandExecuteResult : : FAILED ( st . ToString ( ) ) ;
return ;
}
if ( old_level_num < = new_levels_ ) {
return ;
}
old_levels_ = old_level_num ;
OpenDB ( ) ;
// Compact the whole DB to put all files to the highest level.
fprintf ( stdout , " Compacting the db... \n " ) ;
db_ - > CompactRange ( NULL , NULL ) ;
CloseDB ( ) ;