From dae73790505f63da507af4b8582e310354527633 Mon Sep 17 00:00:00 2001 From: Abhishek Kona Date: Thu, 11 Apr 2013 20:21:49 -0700 Subject: [PATCH] [RocksDB] Expose LDB functioanality as a library call - clients can build their own LDB binary with additional options Summary: Primarily a refactor. Introduced LDBTool interface to which customers can plug in their options and this will create their own version of ldb tool. Test Plan: made ldb tool and tried it. Reviewers: dhruba, heyongqiang Reviewed By: dhruba CC: leveldb Differential Revision: https://reviews.facebook.net/D10191 --- include/leveldb/ldb_tool.h | 14 ++++ tools/ldb.cc | 92 +-------------------- util/ldb_cmd.cc | 162 +++++++++++++++++++++---------------- util/ldb_cmd.h | 64 ++++++++++----- util/ldb_tool.cc | 95 ++++++++++++++++++++++ 5 files changed, 250 insertions(+), 177 deletions(-) create mode 100644 include/leveldb/ldb_tool.h create mode 100644 util/ldb_tool.cc diff --git a/include/leveldb/ldb_tool.h b/include/leveldb/ldb_tool.h new file mode 100644 index 000000000..2b506dc2b --- /dev/null +++ b/include/leveldb/ldb_tool.h @@ -0,0 +1,14 @@ +// Copyright 2008-present Facebook. All Rights Reserved. +#ifndef STORAGE_LEVELDB_INCLUDE_LDB_TOOL_H +#define STORAGE_LEVELDB_INCLUDE_LDB_TOOL_H +#include "leveldb/options.h" + +namespace leveldb { + +class LDBTool { + public: + void Run(int argc, char** argv, Options = Options()); +}; + +} // namespace leveldb +#endif // STORAGE_LEVELDB_INCLUDE_LDB_TOOL_H diff --git a/tools/ldb.cc b/tools/ldb.cc index eeef80b67..8430df7f7 100644 --- a/tools/ldb.cc +++ b/tools/ldb.cc @@ -2,94 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "util/ldb_cmd.h" - -namespace leveldb { - -class LDBCommandRunner { -public: - - static void PrintHelp(const char* exec_name) { - string ret; - - ret.append("ldb - LevelDB Tool"); - ret.append("\n\n"); - ret.append("All commands MUST specify --" + LDBCommand::ARG_DB + - "=\n"); - ret.append("\n"); - ret.append("The following optional parameters control if keys/values are " - "input/output as hex or as plain strings:\n"); - ret.append(" --" + LDBCommand::ARG_KEY_HEX + - " : Keys are input/output as hex\n"); - ret.append(" --" + LDBCommand::ARG_VALUE_HEX + - " : Values are input/output as hex\n"); - ret.append(" --" + LDBCommand::ARG_HEX + - " : Both keys and values are input/output as hex\n"); - ret.append("\n"); - - ret.append("The following optional parameters control the database " - "internals:\n"); - ret.append(" --" + LDBCommand::ARG_BLOOM_BITS + "=\n"); - ret.append(" --" + LDBCommand::ARG_COMPRESSION_TYPE + - "=\n"); - ret.append(" --" + LDBCommand::ARG_BLOCK_SIZE + - "=\n"); - ret.append(" --" + LDBCommand::ARG_AUTO_COMPACTION + "=\n"); - ret.append(" --" + LDBCommand::ARG_WRITE_BUFFER_SIZE + - "=\n"); - ret.append(" --" + LDBCommand::ARG_FILE_SIZE + "=\n"); - - ret.append("\n\n"); - ret.append("Data Access Commands:\n"); - PutCommand::Help(ret); - GetCommand::Help(ret); - BatchPutCommand::Help(ret); - ScanCommand::Help(ret); - DeleteCommand::Help(ret); - DBQuerierCommand::Help(ret); - ApproxSizeCommand::Help(ret); - - ret.append("\n\n"); - ret.append("Admin Commands:\n"); - WALDumperCommand::Help(ret); - CompactorCommand::Help(ret); - ReduceDBLevelsCommand::Help(ret); - DBDumperCommand::Help(ret); - DBLoaderCommand::Help(ret); - ManifestDumpCommand::Help(ret); - - fprintf(stderr, "%s\n", ret.c_str()); - } - - static void RunCommand(int argc, char** argv) { - if (argc <= 2) { - PrintHelp(argv[0]); - exit(1); - } - - LDBCommand* cmdObj = LDBCommand::InitFromCmdLineArgs(argc, argv); - if (cmdObj == nullptr) { - fprintf(stderr, "Unknown command\n"); - PrintHelp(argv[0]); - exit(1); - } - - if (!cmdObj->ValidateCmdLineOptions()) { - exit(1); - } - - cmdObj->Run(); - LDBCommandExecuteResult ret = cmdObj->GetExecuteState(); - fprintf(stderr, "%s\n", ret.ToString().c_str()); - delete cmdObj; - - exit(ret.IsFailed()); - } - -}; - -} +#include "leveldb/ldb_tool.h" int main(int argc, char** argv) { - leveldb::LDBCommandRunner::RunCommand(argc, argv); + leveldb::LDBTool tool; + tool.Run(argc, argv); + return 0; } diff --git a/util/ldb_cmd.cc b/util/ldb_cmd.cc index a5350893d..b52a23075 100644 --- a/util/ldb_cmd.cc +++ b/util/ldb_cmd.cc @@ -46,12 +46,16 @@ const string LDBCommand::ARG_CREATE_IF_MISSING = "create_if_missing"; const char* LDBCommand::DELIM = " ==> "; -LDBCommand* LDBCommand::InitFromCmdLineArgs(int argc, char** argv) { +LDBCommand* LDBCommand::InitFromCmdLineArgs( + int argc, + char** argv, + Options options +) { vector args; for (int i = 1; i < argc; i++) { args.push_back(argv[i]); } - return InitFromCmdLineArgs(args); + return InitFromCmdLineArgs(args, options); } /** @@ -64,14 +68,17 @@ LDBCommand* LDBCommand::InitFromCmdLineArgs(int argc, char** argv) { * Command name is not included in args. * Returns nullptr if the command-line cannot be parsed. */ -LDBCommand* LDBCommand::InitFromCmdLineArgs(const vector& args) { +LDBCommand* LDBCommand::InitFromCmdLineArgs( + const vector& args, + Options options +) { // --x=y command line arguments are added as x->y map entries. - map options; + map option_map; // Command-line arguments of the form --hex end up in this array as hex vector flags; - // Everything other than options and flags. Represents commands + // Everything other than option_map and flags. Represents commands // and their parameters. For eg: put key1 value1 go into this vector. vector cmdTokens; @@ -84,7 +91,7 @@ LDBCommand* LDBCommand::InitFromCmdLineArgs(const vector& args) { vector splits = stringSplit(arg, '='); if (splits.size() == 2) { string optionKey = splits[0].substr(OPTION_PREFIX.size()); - options[optionKey] = splits[1]; + option_map[optionKey] = splits[1]; } else { string optionKey = splits[0].substr(OPTION_PREFIX.size()); flags.push_back(optionKey); @@ -101,38 +108,57 @@ LDBCommand* LDBCommand::InitFromCmdLineArgs(const vector& args) { string cmd = cmdTokens[0]; vector cmdParams(cmdTokens.begin()+1, cmdTokens.end()); + LDBCommand* command = LDBCommand::SelectCommand( + cmd, + cmdParams, + option_map, + flags + ); + + if (command) { + command->SetOptions(options); + } + return command; +} + +LDBCommand* LDBCommand::SelectCommand( + const std::string& cmd, + vector& cmdParams, + map& option_map, + vector& flags + ) { if (cmd == GetCommand::Name()) { - return new GetCommand(cmdParams, options, flags); + return new GetCommand(cmdParams, option_map, flags); } else if (cmd == PutCommand::Name()) { - return new PutCommand(cmdParams, options, flags); + return new PutCommand(cmdParams, option_map, flags); } else if (cmd == BatchPutCommand::Name()) { - return new BatchPutCommand(cmdParams, options, flags); + return new BatchPutCommand(cmdParams, option_map, flags); } else if (cmd == ScanCommand::Name()) { - return new ScanCommand(cmdParams, options, flags); + return new ScanCommand(cmdParams, option_map, flags); } else if (cmd == DeleteCommand::Name()) { - return new DeleteCommand(cmdParams, options, flags); + return new DeleteCommand(cmdParams, option_map, flags); } else if (cmd == ApproxSizeCommand::Name()) { - return new ApproxSizeCommand(cmdParams, options, flags); + return new ApproxSizeCommand(cmdParams, option_map, flags); } else if (cmd == DBQuerierCommand::Name()) { - return new DBQuerierCommand(cmdParams, options, flags); + return new DBQuerierCommand(cmdParams, option_map, flags); } else if (cmd == CompactorCommand::Name()) { - return new CompactorCommand(cmdParams, options, flags); + return new CompactorCommand(cmdParams, option_map, flags); } else if (cmd == WALDumperCommand::Name()) { - return new WALDumperCommand(cmdParams, options, flags); + return new WALDumperCommand(cmdParams, option_map, flags); } else if (cmd == ReduceDBLevelsCommand::Name()) { - return new ReduceDBLevelsCommand(cmdParams, options, flags); + return new ReduceDBLevelsCommand(cmdParams, option_map, flags); } else if (cmd == DBDumperCommand::Name()) { - return new DBDumperCommand(cmdParams, options, flags); + return new DBDumperCommand(cmdParams, option_map, flags); } else if (cmd == DBLoaderCommand::Name()) { - return new DBLoaderCommand(cmdParams, options, flags); + return new DBLoaderCommand(cmdParams, option_map, flags); } else if (cmd == ManifestDumpCommand::Name()) { - return new ManifestDumpCommand(cmdParams, options, flags); + return new ManifestDumpCommand(cmdParams, option_map, flags); } - return nullptr; } + /** * Parses the specific integer option and fills in the value. * Returns true if the option is found. @@ -143,8 +169,8 @@ LDBCommand* LDBCommand::InitFromCmdLineArgs(const vector& args) { bool LDBCommand::ParseIntOption(const map& options, string option, int& value, LDBCommandExecuteResult& exec_state) { - map::const_iterator itr = options_.find(option); - if (itr != options_.end()) { + map::const_iterator itr = option_map_.find(option); + if (itr != option_map_.end()) { try { value = stoi(itr->second); return true; @@ -159,17 +185,17 @@ bool LDBCommand::ParseIntOption(const map& options, return false; } -leveldb::Options LDBCommand::PrepareOptionsForOpenDB() { +Options LDBCommand::PrepareOptionsForOpenDB() { - leveldb::Options opt; + Options opt = options_; opt.create_if_missing = false; map::const_iterator itr; int bits; - if (ParseIntOption(options_, ARG_BLOOM_BITS, bits, exec_state_)) { + if (ParseIntOption(option_map_, ARG_BLOOM_BITS, bits, exec_state_)) { if (bits > 0) { - opt.filter_policy = leveldb::NewBloomFilterPolicy(bits); + opt.filter_policy = NewBloomFilterPolicy(bits); } else { exec_state_ = LDBCommandExecuteResult::FAILED(ARG_BLOOM_BITS + " must be > 0."); @@ -177,7 +203,7 @@ leveldb::Options LDBCommand::PrepareOptionsForOpenDB() { } int block_size; - if (ParseIntOption(options_, ARG_BLOCK_SIZE, block_size, exec_state_)) { + if (ParseIntOption(option_map_, ARG_BLOCK_SIZE, block_size, exec_state_)) { if (block_size > 0) { opt.block_size = block_size; } else { @@ -186,22 +212,22 @@ leveldb::Options LDBCommand::PrepareOptionsForOpenDB() { } } - itr = options_.find(ARG_AUTO_COMPACTION); - if (itr != options_.end()) { + itr = option_map_.find(ARG_AUTO_COMPACTION); + if (itr != option_map_.end()) { opt.disable_auto_compactions = ! StringToBool(itr->second); } - itr = options_.find(ARG_COMPRESSION_TYPE); - if (itr != options_.end()) { + itr = option_map_.find(ARG_COMPRESSION_TYPE); + if (itr != option_map_.end()) { string comp = itr->second; if (comp == "no") { - opt.compression = leveldb::kNoCompression; + opt.compression = kNoCompression; } else if (comp == "snappy") { - opt.compression = leveldb::kSnappyCompression; + opt.compression = kSnappyCompression; } else if (comp == "zlib") { - opt.compression = leveldb::kZlibCompression; + opt.compression = kZlibCompression; } else if (comp == "bzip2") { - opt.compression = leveldb::kBZip2Compression; + opt.compression = kBZip2Compression; } else { // Unknown compression. exec_state_ = LDBCommandExecuteResult::FAILED( @@ -210,7 +236,7 @@ leveldb::Options LDBCommand::PrepareOptionsForOpenDB() { } int write_buffer_size; - if (ParseIntOption(options_, ARG_WRITE_BUFFER_SIZE, write_buffer_size, + if (ParseIntOption(option_map_, ARG_WRITE_BUFFER_SIZE, write_buffer_size, exec_state_)) { if (write_buffer_size > 0) { opt.write_buffer_size = write_buffer_size; @@ -221,7 +247,7 @@ leveldb::Options LDBCommand::PrepareOptionsForOpenDB() { } int file_size; - if (ParseIntOption(options_, ARG_FILE_SIZE, file_size, exec_state_)) { + if (ParseIntOption(option_map_, ARG_FILE_SIZE, file_size, exec_state_)) { if (file_size > 0) { opt.target_file_size_base = file_size; } else { @@ -260,8 +286,8 @@ bool LDBCommand::ParseKeyValue(const string& line, string* key, string* value, */ bool LDBCommand::ValidateCmdLineOptions() { - for (map::const_iterator itr = options_.begin(); - itr != options_.end(); itr++) { + for (map::const_iterator itr = option_map_.begin(); + itr != option_map_.end(); itr++) { if (find(valid_cmd_line_options_.begin(), valid_cmd_line_options_.end(), itr->first) == valid_cmd_line_options_.end()) { @@ -280,7 +306,7 @@ bool LDBCommand::ValidateCmdLineOptions() { } } - if (options_.find(ARG_DB) == options_.end()) { + if (!NoDBOpen() && option_map_.find(ARG_DB) == option_map_.end()) { fprintf(stderr, "%s must be specified\n", ARG_DB.c_str()); return false; } @@ -326,13 +352,13 @@ void CompactorCommand::Help(string& ret) { void CompactorCommand::DoCommand() { - leveldb::Slice* begin = nullptr; - leveldb::Slice* end = nullptr; + Slice* begin = nullptr; + Slice* end = nullptr; if (!null_from_) { - begin = new leveldb::Slice(from_); + begin = new Slice(from_); } if (!null_to_) { - end = new leveldb::Slice(to_); + end = new Slice(to_); } db_->CompactRange(begin, end); @@ -372,8 +398,8 @@ void DBLoaderCommand::Help(string& ret) { ret.append("\n"); } -leveldb::Options DBLoaderCommand::PrepareOptionsForOpenDB() { - leveldb::Options opt = LDBCommand::PrepareOptionsForOpenDB(); +Options DBLoaderCommand::PrepareOptionsForOpenDB() { + Options opt = LDBCommand::PrepareOptionsForOpenDB(); opt.create_if_missing = create_if_missing_; if (bulk_load_) { opt.PrepareForBulkLoad(); @@ -583,8 +609,8 @@ void DBDumperCommand::DoCommand() { } // Setup key iterator - leveldb::Iterator* iter = db_->NewIterator(leveldb::ReadOptions()); - leveldb::Status st = iter->status(); + Iterator* iter = db_->NewIterator(ReadOptions()); + Status st = iter->status(); if (!st.ok()) { exec_state_ = LDBCommandExecuteResult::FAILED("Iterator error." + st.ToString()); @@ -632,7 +658,7 @@ ReduceDBLevelsCommand::ReduceDBLevelsCommand(const vector& params, print_old_levels_(false) { - ParseIntOption(options_, ARG_NEW_LEVELS, new_levels_, exec_state_); + ParseIntOption(option_map_, ARG_NEW_LEVELS, new_levels_, exec_state_); print_old_levels_ = IsFlagPresent(flags, ARG_PRINT_OLD_LEVELS); if(new_levels_ <= 0) { @@ -661,8 +687,8 @@ void ReduceDBLevelsCommand::Help(string& ret) { ret.append("\n"); } -leveldb::Options ReduceDBLevelsCommand::PrepareOptionsForOpenDB() { - leveldb::Options opt = LDBCommand::PrepareOptionsForOpenDB(); +Options ReduceDBLevelsCommand::PrepareOptionsForOpenDB() { + Options opt = LDBCommand::PrepareOptionsForOpenDB(); opt.num_levels = old_levels_; // Disable size compaction opt.max_bytes_for_level_base = 1UL << 50; @@ -671,7 +697,7 @@ leveldb::Options ReduceDBLevelsCommand::PrepareOptionsForOpenDB() { return opt; } -Status ReduceDBLevelsCommand::GetOldNumOfLevels(leveldb::Options& opt, +Status ReduceDBLevelsCommand::GetOldNumOfLevels(Options& opt, int* levels) { StorageOptions soptions; TableCache tc(db_path_, &opt, soptions, 10); @@ -702,8 +728,8 @@ void ReduceDBLevelsCommand::DoCommand() { return; } - leveldb::Status st; - leveldb::Options opt = PrepareOptionsForOpenDB(); + Status st; + Options opt = PrepareOptionsForOpenDB(); int old_level_num = -1; st = GetOldNumOfLevels(opt, &old_level_num); if (!st.ok()) { @@ -906,7 +932,7 @@ void GetCommand::Help(string& ret) { void GetCommand::DoCommand() { string value; - leveldb::Status st = db_->Get(leveldb::ReadOptions(), key_, &value); + Status st = db_->Get(ReadOptions(), key_, &value); if (st.ok()) { fprintf(stdout, "%s\n", (is_value_hex_ ? StringToHex(value) : value).c_str()); @@ -953,8 +979,8 @@ void ApproxSizeCommand::Help(string& ret) { void ApproxSizeCommand::DoCommand() { - leveldb::Range ranges[1]; - ranges[0] = leveldb::Range(start_key_, end_key_); + Range ranges[1]; + ranges[0] = Range(start_key_, end_key_); uint64_t sizes[1]; db_->GetApproximateSizes(ranges, 1, sizes); fprintf(stdout, "%ld\n", sizes[0]); @@ -998,13 +1024,13 @@ void BatchPutCommand::Help(string& ret) { } void BatchPutCommand::DoCommand() { - leveldb::WriteBatch batch; + WriteBatch batch; for (vector>::const_iterator itr = key_values_.begin(); itr != key_values_.end(); itr++) { batch.Put(itr->first, itr->second); } - leveldb::Status st = db_->Write(leveldb::WriteOptions(), &batch); + Status st = db_->Write(WriteOptions(), &batch); if (st.ok()) { fprintf(stdout, "OK\n"); } else { @@ -1012,8 +1038,8 @@ void BatchPutCommand::DoCommand() { } } -leveldb::Options BatchPutCommand::PrepareOptionsForOpenDB() { - leveldb::Options opt = LDBCommand::PrepareOptionsForOpenDB(); +Options BatchPutCommand::PrepareOptionsForOpenDB() { + Options opt = LDBCommand::PrepareOptionsForOpenDB(); opt.create_if_missing = IsFlagPresent(flags_, ARG_CREATE_IF_MISSING); return opt; } @@ -1070,7 +1096,7 @@ void ScanCommand::Help(string& ret) { void ScanCommand::DoCommand() { int num_keys_scanned = 0; - Iterator* it = db_->NewIterator(leveldb::ReadOptions()); + Iterator* it = db_->NewIterator(ReadOptions()); if (start_key_specified_) { it->Seek(start_key_); } else { @@ -1120,7 +1146,7 @@ void DeleteCommand::Help(string& ret) { } void DeleteCommand::DoCommand() { - leveldb::Status st = db_->Delete(leveldb::WriteOptions(), key_); + Status st = db_->Delete(WriteOptions(), key_); if (st.ok()) { fprintf(stdout, "OK\n"); } else { @@ -1160,7 +1186,7 @@ void PutCommand::Help(string& ret) { } void PutCommand::DoCommand() { - leveldb::Status st = db_->Put(leveldb::WriteOptions(), key_, value_); + Status st = db_->Put(WriteOptions(), key_, value_); if (st.ok()) { fprintf(stdout, "OK\n"); } else { @@ -1168,8 +1194,8 @@ void PutCommand::DoCommand() { } } -leveldb::Options PutCommand::PrepareOptionsForOpenDB() { - leveldb::Options opt = LDBCommand::PrepareOptionsForOpenDB(); +Options PutCommand::PrepareOptionsForOpenDB() { + Options opt = LDBCommand::PrepareOptionsForOpenDB(); opt.create_if_missing = IsFlagPresent(flags_, ARG_CREATE_IF_MISSING); return opt; } @@ -1201,8 +1227,8 @@ void DBQuerierCommand::DoCommand() { return; } - leveldb::ReadOptions read_options; - leveldb::WriteOptions write_options; + ReadOptions read_options; + WriteOptions write_options; string line; string key; diff --git a/util/ldb_cmd.h b/util/ldb_cmd.h index 0ea77dae1..77ba58128 100644 --- a/util/ldb_cmd.h +++ b/util/ldb_cmd.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef LEVELDB_UTIL_LDB_CMD_H_ -#define LEVELDB_UTIL_LDB_CMD_H_ +#ifndef STORAGE_LEVELDB_UTIL_LDB_CMD_H_ +#define STORAGE_LEVELDB_UTIL_LDB_CMD_H_ #include #include @@ -47,11 +47,24 @@ public: static const string ARG_FILE_SIZE; static const string ARG_CREATE_IF_MISSING; - static LDBCommand* InitFromCmdLineArgs(const vector& args); - static LDBCommand* InitFromCmdLineArgs(int argc, char** argv); + static LDBCommand* InitFromCmdLineArgs( + const vector& args, + Options options = Options() + ); + + static LDBCommand* InitFromCmdLineArgs( + int argc, + char** argv, + Options options = Options() + ); + bool ValidateCmdLineOptions(); - virtual leveldb::Options PrepareOptionsForOpenDB(); + virtual Options PrepareOptionsForOpenDB(); + + virtual void SetOptions(Options options) { + options_ = options; + } virtual bool NoDBOpen() { return false; @@ -129,8 +142,8 @@ public: protected: LDBCommandExecuteResult exec_state_; - std::string db_path_; - leveldb::DB* db_; + string db_path_; + DB* db_; /** * true implies that this command can work if the db is opened in read-only @@ -147,7 +160,7 @@ protected: /** * Map of options passed on the command-line. */ - const map options_; + const map option_map_; /** * Flags passed on the command-line. @@ -166,7 +179,7 @@ protected: is_read_only_(is_read_only), is_key_hex_(false), is_value_hex_(false), - options_(options), + option_map_(options), flags_(flags), valid_cmd_line_options_(valid_cmd_line_options) { @@ -180,19 +193,19 @@ protected: } void OpenDB() { - leveldb::Options opt = PrepareOptionsForOpenDB(); + Options opt = PrepareOptionsForOpenDB(); if (!exec_state_.IsNotStarted()) { return; } // Open the DB. - leveldb::Status st; + Status st; if (is_read_only_) { - st = leveldb::DB::OpenForReadOnly(opt, db_path_, &db_); + st = DB::OpenForReadOnly(opt, db_path_, &db_); } else { - st = leveldb::DB::Open(opt, db_path_, &db_); + st = DB::Open(opt, db_path_, &db_); } if (!st.ok()) { - std::string msg = st.ToString(); + string msg = st.ToString(); exec_state_ = LDBCommandExecuteResult::FAILED(msg); } } @@ -251,6 +264,8 @@ protected: private: + Options options_; + /** * Interpret command line options and flags to determine if the key * should be input/output in hex. @@ -308,6 +323,13 @@ private: } } + static LDBCommand* SelectCommand( + const string& cmd, + vector& cmdParams, + map& option_map, + vector& flags + ); + }; class CompactorCommand: public LDBCommand { @@ -364,7 +386,7 @@ public: static void Help(string& ret); virtual void DoCommand(); - virtual leveldb::Options PrepareOptionsForOpenDB(); + virtual Options PrepareOptionsForOpenDB(); private: bool create_if_missing_; @@ -406,7 +428,7 @@ public: ReduceDBLevelsCommand(const vector& params, const map& options, const vector& flags); - virtual leveldb::Options PrepareOptionsForOpenDB(); + virtual Options PrepareOptionsForOpenDB(); virtual void DoCommand(); @@ -427,7 +449,7 @@ private: static const string ARG_NEW_LEVELS; static const string ARG_PRINT_OLD_LEVELS; - Status GetOldNumOfLevels(leveldb::Options& opt, int* levels); + Status GetOldNumOfLevels(Options& opt, int* levels); }; class WALDumperCommand : public LDBCommand { @@ -497,7 +519,7 @@ public: static void Help(string& ret); - virtual leveldb::Options PrepareOptionsForOpenDB(); + virtual Options PrepareOptionsForOpenDB(); private: /** @@ -551,7 +573,7 @@ public: static void Help(string& ret); - virtual leveldb::Options PrepareOptionsForOpenDB(); + virtual Options PrepareOptionsForOpenDB(); private: string key_; @@ -580,5 +602,5 @@ private: static const char* DELETE_CMD; }; -} -#endif +} // namespace leveldb +#endif // STORAGE_LEVELDB_UTIL_LDB_CMD_H_ diff --git a/util/ldb_tool.cc b/util/ldb_tool.cc new file mode 100644 index 000000000..2d46bce2e --- /dev/null +++ b/util/ldb_tool.cc @@ -0,0 +1,95 @@ +// Copyright 2008-present Facebook. All Rights Reserved. + +#include "leveldb/ldb_tool.h" +#include "util/ldb_cmd.h" + +namespace leveldb { + +class LDBCommandRunner { +public: + + static void PrintHelp(const char* exec_name) { + string ret; + + ret.append("ldb - LevelDB Tool"); + ret.append("\n\n"); + ret.append("commands MUST specify --" + LDBCommand::ARG_DB + + "= when necessary\n"); + ret.append("\n"); + ret.append("The following optional parameters control if keys/values are " + "input/output as hex or as plain strings:\n"); + ret.append(" --" + LDBCommand::ARG_KEY_HEX + + " : Keys are input/output as hex\n"); + ret.append(" --" + LDBCommand::ARG_VALUE_HEX + + " : Values are input/output as hex\n"); + ret.append(" --" + LDBCommand::ARG_HEX + + " : Both keys and values are input/output as hex\n"); + ret.append("\n"); + + ret.append("The following optional parameters control the database " + "internals:\n"); + ret.append(" --" + LDBCommand::ARG_BLOOM_BITS + "=\n"); + ret.append(" --" + LDBCommand::ARG_COMPRESSION_TYPE + + "=\n"); + ret.append(" --" + LDBCommand::ARG_BLOCK_SIZE + + "=\n"); + ret.append(" --" + LDBCommand::ARG_AUTO_COMPACTION + "=\n"); + ret.append(" --" + LDBCommand::ARG_WRITE_BUFFER_SIZE + + "=\n"); + ret.append(" --" + LDBCommand::ARG_FILE_SIZE + "=\n"); + + ret.append("\n\n"); + ret.append("Data Access Commands:\n"); + PutCommand::Help(ret); + GetCommand::Help(ret); + BatchPutCommand::Help(ret); + ScanCommand::Help(ret); + DeleteCommand::Help(ret); + DBQuerierCommand::Help(ret); + ApproxSizeCommand::Help(ret); + + ret.append("\n\n"); + ret.append("Admin Commands:\n"); + WALDumperCommand::Help(ret); + CompactorCommand::Help(ret); + ReduceDBLevelsCommand::Help(ret); + DBDumperCommand::Help(ret); + DBLoaderCommand::Help(ret); + ManifestDumpCommand::Help(ret); + + fprintf(stderr, "%s\n", ret.c_str()); + } + + static void RunCommand(int argc, char** argv, Options options) { + if (argc <= 2) { + PrintHelp(argv[0]); + exit(1); + } + + LDBCommand* cmdObj = LDBCommand::InitFromCmdLineArgs(argc, argv, options); + if (cmdObj == nullptr) { + fprintf(stderr, "Unknown command\n"); + PrintHelp(argv[0]); + exit(1); + } + + if (!cmdObj->ValidateCmdLineOptions()) { + exit(1); + } + + cmdObj->Run(); + LDBCommandExecuteResult ret = cmdObj->GetExecuteState(); + fprintf(stderr, "%s\n", ret.ToString().c_str()); + delete cmdObj; + + exit(ret.IsFailed()); + } + +}; + + +void LDBTool::Run(int argc, char** argv, Options options) { + LDBCommandRunner::RunCommand(argc, argv, options); +} +} // namespace leveldb +