[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
main
Abhishek Kona 12 years ago
parent 94d86b25a9
commit dae7379050
  1. 14
      include/leveldb/ldb_tool.h
  2. 92
      tools/ldb.cc
  3. 162
      util/ldb_cmd.cc
  4. 64
      util/ldb_cmd.h
  5. 95
      util/ldb_tool.cc

@ -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

@ -2,94 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "util/ldb_cmd.h" #include "leveldb/ldb_tool.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 +
"=<full_path_to_db_directory>\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 + "=<int,e.g.:14>\n");
ret.append(" --" + LDBCommand::ARG_COMPRESSION_TYPE +
"=<no|snappy|zlib|bzip2>\n");
ret.append(" --" + LDBCommand::ARG_BLOCK_SIZE +
"=<block_size_in_bytes>\n");
ret.append(" --" + LDBCommand::ARG_AUTO_COMPACTION + "=<true|false>\n");
ret.append(" --" + LDBCommand::ARG_WRITE_BUFFER_SIZE +
"=<int,e.g.:4194304>\n");
ret.append(" --" + LDBCommand::ARG_FILE_SIZE + "=<int,e.g.:2097152>\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());
}
};
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
leveldb::LDBCommandRunner::RunCommand(argc, argv); leveldb::LDBTool tool;
tool.Run(argc, argv);
return 0;
} }

@ -46,12 +46,16 @@ const string LDBCommand::ARG_CREATE_IF_MISSING = "create_if_missing";
const char* LDBCommand::DELIM = " ==> "; const char* LDBCommand::DELIM = " ==> ";
LDBCommand* LDBCommand::InitFromCmdLineArgs(int argc, char** argv) { LDBCommand* LDBCommand::InitFromCmdLineArgs(
int argc,
char** argv,
Options options
) {
vector<string> args; vector<string> args;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
args.push_back(argv[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. * Command name is not included in args.
* Returns nullptr if the command-line cannot be parsed. * Returns nullptr if the command-line cannot be parsed.
*/ */
LDBCommand* LDBCommand::InitFromCmdLineArgs(const vector<string>& args) { LDBCommand* LDBCommand::InitFromCmdLineArgs(
const vector<string>& args,
Options options
) {
// --x=y command line arguments are added as x->y map entries. // --x=y command line arguments are added as x->y map entries.
map<string, string> options; map<string, string> option_map;
// Command-line arguments of the form --hex end up in this array as hex // Command-line arguments of the form --hex end up in this array as hex
vector<string> flags; vector<string> 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. // and their parameters. For eg: put key1 value1 go into this vector.
vector<string> cmdTokens; vector<string> cmdTokens;
@ -84,7 +91,7 @@ LDBCommand* LDBCommand::InitFromCmdLineArgs(const vector<string>& args) {
vector<string> splits = stringSplit(arg, '='); vector<string> splits = stringSplit(arg, '=');
if (splits.size() == 2) { if (splits.size() == 2) {
string optionKey = splits[0].substr(OPTION_PREFIX.size()); string optionKey = splits[0].substr(OPTION_PREFIX.size());
options[optionKey] = splits[1]; option_map[optionKey] = splits[1];
} else { } else {
string optionKey = splits[0].substr(OPTION_PREFIX.size()); string optionKey = splits[0].substr(OPTION_PREFIX.size());
flags.push_back(optionKey); flags.push_back(optionKey);
@ -101,38 +108,57 @@ LDBCommand* LDBCommand::InitFromCmdLineArgs(const vector<string>& args) {
string cmd = cmdTokens[0]; string cmd = cmdTokens[0];
vector<string> cmdParams(cmdTokens.begin()+1, cmdTokens.end()); vector<string> 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<string>& cmdParams,
map<string, string>& option_map,
vector<string>& flags
) {
if (cmd == GetCommand::Name()) { if (cmd == GetCommand::Name()) {
return new GetCommand(cmdParams, options, flags); return new GetCommand(cmdParams, option_map, flags);
} else if (cmd == PutCommand::Name()) { } else if (cmd == PutCommand::Name()) {
return new PutCommand(cmdParams, options, flags); return new PutCommand(cmdParams, option_map, flags);
} else if (cmd == BatchPutCommand::Name()) { } else if (cmd == BatchPutCommand::Name()) {
return new BatchPutCommand(cmdParams, options, flags); return new BatchPutCommand(cmdParams, option_map, flags);
} else if (cmd == ScanCommand::Name()) { } else if (cmd == ScanCommand::Name()) {
return new ScanCommand(cmdParams, options, flags); return new ScanCommand(cmdParams, option_map, flags);
} else if (cmd == DeleteCommand::Name()) { } else if (cmd == DeleteCommand::Name()) {
return new DeleteCommand(cmdParams, options, flags); return new DeleteCommand(cmdParams, option_map, flags);
} else if (cmd == ApproxSizeCommand::Name()) { } else if (cmd == ApproxSizeCommand::Name()) {
return new ApproxSizeCommand(cmdParams, options, flags); return new ApproxSizeCommand(cmdParams, option_map, flags);
} else if (cmd == DBQuerierCommand::Name()) { } else if (cmd == DBQuerierCommand::Name()) {
return new DBQuerierCommand(cmdParams, options, flags); return new DBQuerierCommand(cmdParams, option_map, flags);
} else if (cmd == CompactorCommand::Name()) { } else if (cmd == CompactorCommand::Name()) {
return new CompactorCommand(cmdParams, options, flags); return new CompactorCommand(cmdParams, option_map, flags);
} else if (cmd == WALDumperCommand::Name()) { } else if (cmd == WALDumperCommand::Name()) {
return new WALDumperCommand(cmdParams, options, flags); return new WALDumperCommand(cmdParams, option_map, flags);
} else if (cmd == ReduceDBLevelsCommand::Name()) { } else if (cmd == ReduceDBLevelsCommand::Name()) {
return new ReduceDBLevelsCommand(cmdParams, options, flags); return new ReduceDBLevelsCommand(cmdParams, option_map, flags);
} else if (cmd == DBDumperCommand::Name()) { } else if (cmd == DBDumperCommand::Name()) {
return new DBDumperCommand(cmdParams, options, flags); return new DBDumperCommand(cmdParams, option_map, flags);
} else if (cmd == DBLoaderCommand::Name()) { } else if (cmd == DBLoaderCommand::Name()) {
return new DBLoaderCommand(cmdParams, options, flags); return new DBLoaderCommand(cmdParams, option_map, flags);
} else if (cmd == ManifestDumpCommand::Name()) { } else if (cmd == ManifestDumpCommand::Name()) {
return new ManifestDumpCommand(cmdParams, options, flags); return new ManifestDumpCommand(cmdParams, option_map, flags);
} }
return nullptr; return nullptr;
} }
/** /**
* Parses the specific integer option and fills in the value. * Parses the specific integer option and fills in the value.
* Returns true if the option is found. * Returns true if the option is found.
@ -143,8 +169,8 @@ LDBCommand* LDBCommand::InitFromCmdLineArgs(const vector<string>& args) {
bool LDBCommand::ParseIntOption(const map<string, string>& options, bool LDBCommand::ParseIntOption(const map<string, string>& options,
string option, int& value, LDBCommandExecuteResult& exec_state) { string option, int& value, LDBCommandExecuteResult& exec_state) {
map<string, string>::const_iterator itr = options_.find(option); map<string, string>::const_iterator itr = option_map_.find(option);
if (itr != options_.end()) { if (itr != option_map_.end()) {
try { try {
value = stoi(itr->second); value = stoi(itr->second);
return true; return true;
@ -159,17 +185,17 @@ bool LDBCommand::ParseIntOption(const map<string, string>& options,
return false; return false;
} }
leveldb::Options LDBCommand::PrepareOptionsForOpenDB() { Options LDBCommand::PrepareOptionsForOpenDB() {
leveldb::Options opt; Options opt = options_;
opt.create_if_missing = false; opt.create_if_missing = false;
map<string, string>::const_iterator itr; map<string, string>::const_iterator itr;
int bits; int bits;
if (ParseIntOption(options_, ARG_BLOOM_BITS, bits, exec_state_)) { if (ParseIntOption(option_map_, ARG_BLOOM_BITS, bits, exec_state_)) {
if (bits > 0) { if (bits > 0) {
opt.filter_policy = leveldb::NewBloomFilterPolicy(bits); opt.filter_policy = NewBloomFilterPolicy(bits);
} else { } else {
exec_state_ = LDBCommandExecuteResult::FAILED(ARG_BLOOM_BITS + exec_state_ = LDBCommandExecuteResult::FAILED(ARG_BLOOM_BITS +
" must be > 0."); " must be > 0.");
@ -177,7 +203,7 @@ leveldb::Options LDBCommand::PrepareOptionsForOpenDB() {
} }
int block_size; 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) { if (block_size > 0) {
opt.block_size = block_size; opt.block_size = block_size;
} else { } else {
@ -186,22 +212,22 @@ leveldb::Options LDBCommand::PrepareOptionsForOpenDB() {
} }
} }
itr = options_.find(ARG_AUTO_COMPACTION); itr = option_map_.find(ARG_AUTO_COMPACTION);
if (itr != options_.end()) { if (itr != option_map_.end()) {
opt.disable_auto_compactions = ! StringToBool(itr->second); opt.disable_auto_compactions = ! StringToBool(itr->second);
} }
itr = options_.find(ARG_COMPRESSION_TYPE); itr = option_map_.find(ARG_COMPRESSION_TYPE);
if (itr != options_.end()) { if (itr != option_map_.end()) {
string comp = itr->second; string comp = itr->second;
if (comp == "no") { if (comp == "no") {
opt.compression = leveldb::kNoCompression; opt.compression = kNoCompression;
} else if (comp == "snappy") { } else if (comp == "snappy") {
opt.compression = leveldb::kSnappyCompression; opt.compression = kSnappyCompression;
} else if (comp == "zlib") { } else if (comp == "zlib") {
opt.compression = leveldb::kZlibCompression; opt.compression = kZlibCompression;
} else if (comp == "bzip2") { } else if (comp == "bzip2") {
opt.compression = leveldb::kBZip2Compression; opt.compression = kBZip2Compression;
} else { } else {
// Unknown compression. // Unknown compression.
exec_state_ = LDBCommandExecuteResult::FAILED( exec_state_ = LDBCommandExecuteResult::FAILED(
@ -210,7 +236,7 @@ leveldb::Options LDBCommand::PrepareOptionsForOpenDB() {
} }
int write_buffer_size; 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_)) { exec_state_)) {
if (write_buffer_size > 0) { if (write_buffer_size > 0) {
opt.write_buffer_size = write_buffer_size; opt.write_buffer_size = write_buffer_size;
@ -221,7 +247,7 @@ leveldb::Options LDBCommand::PrepareOptionsForOpenDB() {
} }
int file_size; 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) { if (file_size > 0) {
opt.target_file_size_base = file_size; opt.target_file_size_base = file_size;
} else { } else {
@ -260,8 +286,8 @@ bool LDBCommand::ParseKeyValue(const string& line, string* key, string* value,
*/ */
bool LDBCommand::ValidateCmdLineOptions() { bool LDBCommand::ValidateCmdLineOptions() {
for (map<string, string>::const_iterator itr = options_.begin(); for (map<string, string>::const_iterator itr = option_map_.begin();
itr != options_.end(); itr++) { itr != option_map_.end(); itr++) {
if (find(valid_cmd_line_options_.begin(), if (find(valid_cmd_line_options_.begin(),
valid_cmd_line_options_.end(), itr->first) == valid_cmd_line_options_.end(), itr->first) ==
valid_cmd_line_options_.end()) { 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()); fprintf(stderr, "%s must be specified\n", ARG_DB.c_str());
return false; return false;
} }
@ -326,13 +352,13 @@ void CompactorCommand::Help(string& ret) {
void CompactorCommand::DoCommand() { void CompactorCommand::DoCommand() {
leveldb::Slice* begin = nullptr; Slice* begin = nullptr;
leveldb::Slice* end = nullptr; Slice* end = nullptr;
if (!null_from_) { if (!null_from_) {
begin = new leveldb::Slice(from_); begin = new Slice(from_);
} }
if (!null_to_) { if (!null_to_) {
end = new leveldb::Slice(to_); end = new Slice(to_);
} }
db_->CompactRange(begin, end); db_->CompactRange(begin, end);
@ -372,8 +398,8 @@ void DBLoaderCommand::Help(string& ret) {
ret.append("\n"); ret.append("\n");
} }
leveldb::Options DBLoaderCommand::PrepareOptionsForOpenDB() { Options DBLoaderCommand::PrepareOptionsForOpenDB() {
leveldb::Options opt = LDBCommand::PrepareOptionsForOpenDB(); Options opt = LDBCommand::PrepareOptionsForOpenDB();
opt.create_if_missing = create_if_missing_; opt.create_if_missing = create_if_missing_;
if (bulk_load_) { if (bulk_load_) {
opt.PrepareForBulkLoad(); opt.PrepareForBulkLoad();
@ -583,8 +609,8 @@ void DBDumperCommand::DoCommand() {
} }
// Setup key iterator // Setup key iterator
leveldb::Iterator* iter = db_->NewIterator(leveldb::ReadOptions()); Iterator* iter = db_->NewIterator(ReadOptions());
leveldb::Status st = iter->status(); Status st = iter->status();
if (!st.ok()) { if (!st.ok()) {
exec_state_ = LDBCommandExecuteResult::FAILED("Iterator error." exec_state_ = LDBCommandExecuteResult::FAILED("Iterator error."
+ st.ToString()); + st.ToString());
@ -632,7 +658,7 @@ ReduceDBLevelsCommand::ReduceDBLevelsCommand(const vector<string>& params,
print_old_levels_(false) { 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); print_old_levels_ = IsFlagPresent(flags, ARG_PRINT_OLD_LEVELS);
if(new_levels_ <= 0) { if(new_levels_ <= 0) {
@ -661,8 +687,8 @@ void ReduceDBLevelsCommand::Help(string& ret) {
ret.append("\n"); ret.append("\n");
} }
leveldb::Options ReduceDBLevelsCommand::PrepareOptionsForOpenDB() { Options ReduceDBLevelsCommand::PrepareOptionsForOpenDB() {
leveldb::Options opt = LDBCommand::PrepareOptionsForOpenDB(); Options opt = LDBCommand::PrepareOptionsForOpenDB();
opt.num_levels = old_levels_; opt.num_levels = old_levels_;
// Disable size compaction // Disable size compaction
opt.max_bytes_for_level_base = 1UL << 50; opt.max_bytes_for_level_base = 1UL << 50;
@ -671,7 +697,7 @@ leveldb::Options ReduceDBLevelsCommand::PrepareOptionsForOpenDB() {
return opt; return opt;
} }
Status ReduceDBLevelsCommand::GetOldNumOfLevels(leveldb::Options& opt, Status ReduceDBLevelsCommand::GetOldNumOfLevels(Options& opt,
int* levels) { int* levels) {
StorageOptions soptions; StorageOptions soptions;
TableCache tc(db_path_, &opt, soptions, 10); TableCache tc(db_path_, &opt, soptions, 10);
@ -702,8 +728,8 @@ void ReduceDBLevelsCommand::DoCommand() {
return; return;
} }
leveldb::Status st; Status st;
leveldb::Options opt = PrepareOptionsForOpenDB(); Options opt = PrepareOptionsForOpenDB();
int old_level_num = -1; int old_level_num = -1;
st = GetOldNumOfLevels(opt, &old_level_num); st = GetOldNumOfLevels(opt, &old_level_num);
if (!st.ok()) { if (!st.ok()) {
@ -906,7 +932,7 @@ void GetCommand::Help(string& ret) {
void GetCommand::DoCommand() { void GetCommand::DoCommand() {
string value; string value;
leveldb::Status st = db_->Get(leveldb::ReadOptions(), key_, &value); Status st = db_->Get(ReadOptions(), key_, &value);
if (st.ok()) { if (st.ok()) {
fprintf(stdout, "%s\n", fprintf(stdout, "%s\n",
(is_value_hex_ ? StringToHex(value) : value).c_str()); (is_value_hex_ ? StringToHex(value) : value).c_str());
@ -953,8 +979,8 @@ void ApproxSizeCommand::Help(string& ret) {
void ApproxSizeCommand::DoCommand() { void ApproxSizeCommand::DoCommand() {
leveldb::Range ranges[1]; Range ranges[1];
ranges[0] = leveldb::Range(start_key_, end_key_); ranges[0] = Range(start_key_, end_key_);
uint64_t sizes[1]; uint64_t sizes[1];
db_->GetApproximateSizes(ranges, 1, sizes); db_->GetApproximateSizes(ranges, 1, sizes);
fprintf(stdout, "%ld\n", sizes[0]); fprintf(stdout, "%ld\n", sizes[0]);
@ -998,13 +1024,13 @@ void BatchPutCommand::Help(string& ret) {
} }
void BatchPutCommand::DoCommand() { void BatchPutCommand::DoCommand() {
leveldb::WriteBatch batch; WriteBatch batch;
for (vector<pair<string, string>>::const_iterator itr for (vector<pair<string, string>>::const_iterator itr
= key_values_.begin(); itr != key_values_.end(); itr++) { = key_values_.begin(); itr != key_values_.end(); itr++) {
batch.Put(itr->first, itr->second); batch.Put(itr->first, itr->second);
} }
leveldb::Status st = db_->Write(leveldb::WriteOptions(), &batch); Status st = db_->Write(WriteOptions(), &batch);
if (st.ok()) { if (st.ok()) {
fprintf(stdout, "OK\n"); fprintf(stdout, "OK\n");
} else { } else {
@ -1012,8 +1038,8 @@ void BatchPutCommand::DoCommand() {
} }
} }
leveldb::Options BatchPutCommand::PrepareOptionsForOpenDB() { Options BatchPutCommand::PrepareOptionsForOpenDB() {
leveldb::Options opt = LDBCommand::PrepareOptionsForOpenDB(); Options opt = LDBCommand::PrepareOptionsForOpenDB();
opt.create_if_missing = IsFlagPresent(flags_, ARG_CREATE_IF_MISSING); opt.create_if_missing = IsFlagPresent(flags_, ARG_CREATE_IF_MISSING);
return opt; return opt;
} }
@ -1070,7 +1096,7 @@ void ScanCommand::Help(string& ret) {
void ScanCommand::DoCommand() { void ScanCommand::DoCommand() {
int num_keys_scanned = 0; int num_keys_scanned = 0;
Iterator* it = db_->NewIterator(leveldb::ReadOptions()); Iterator* it = db_->NewIterator(ReadOptions());
if (start_key_specified_) { if (start_key_specified_) {
it->Seek(start_key_); it->Seek(start_key_);
} else { } else {
@ -1120,7 +1146,7 @@ void DeleteCommand::Help(string& ret) {
} }
void DeleteCommand::DoCommand() { void DeleteCommand::DoCommand() {
leveldb::Status st = db_->Delete(leveldb::WriteOptions(), key_); Status st = db_->Delete(WriteOptions(), key_);
if (st.ok()) { if (st.ok()) {
fprintf(stdout, "OK\n"); fprintf(stdout, "OK\n");
} else { } else {
@ -1160,7 +1186,7 @@ void PutCommand::Help(string& ret) {
} }
void PutCommand::DoCommand() { void PutCommand::DoCommand() {
leveldb::Status st = db_->Put(leveldb::WriteOptions(), key_, value_); Status st = db_->Put(WriteOptions(), key_, value_);
if (st.ok()) { if (st.ok()) {
fprintf(stdout, "OK\n"); fprintf(stdout, "OK\n");
} else { } else {
@ -1168,8 +1194,8 @@ void PutCommand::DoCommand() {
} }
} }
leveldb::Options PutCommand::PrepareOptionsForOpenDB() { Options PutCommand::PrepareOptionsForOpenDB() {
leveldb::Options opt = LDBCommand::PrepareOptionsForOpenDB(); Options opt = LDBCommand::PrepareOptionsForOpenDB();
opt.create_if_missing = IsFlagPresent(flags_, ARG_CREATE_IF_MISSING); opt.create_if_missing = IsFlagPresent(flags_, ARG_CREATE_IF_MISSING);
return opt; return opt;
} }
@ -1201,8 +1227,8 @@ void DBQuerierCommand::DoCommand() {
return; return;
} }
leveldb::ReadOptions read_options; ReadOptions read_options;
leveldb::WriteOptions write_options; WriteOptions write_options;
string line; string line;
string key; string key;

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef LEVELDB_UTIL_LDB_CMD_H_ #ifndef STORAGE_LEVELDB_UTIL_LDB_CMD_H_
#define LEVELDB_UTIL_LDB_CMD_H_ #define STORAGE_LEVELDB_UTIL_LDB_CMD_H_
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -47,11 +47,24 @@ public:
static const string ARG_FILE_SIZE; static const string ARG_FILE_SIZE;
static const string ARG_CREATE_IF_MISSING; static const string ARG_CREATE_IF_MISSING;
static LDBCommand* InitFromCmdLineArgs(const vector<string>& args); static LDBCommand* InitFromCmdLineArgs(
static LDBCommand* InitFromCmdLineArgs(int argc, char** argv); const vector<string>& args,
Options options = Options()
);
static LDBCommand* InitFromCmdLineArgs(
int argc,
char** argv,
Options options = Options()
);
bool ValidateCmdLineOptions(); bool ValidateCmdLineOptions();
virtual leveldb::Options PrepareOptionsForOpenDB(); virtual Options PrepareOptionsForOpenDB();
virtual void SetOptions(Options options) {
options_ = options;
}
virtual bool NoDBOpen() { virtual bool NoDBOpen() {
return false; return false;
@ -129,8 +142,8 @@ public:
protected: protected:
LDBCommandExecuteResult exec_state_; LDBCommandExecuteResult exec_state_;
std::string db_path_; string db_path_;
leveldb::DB* db_; DB* db_;
/** /**
* true implies that this command can work if the db is opened in read-only * 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. * Map of options passed on the command-line.
*/ */
const map<string, string> options_; const map<string, string> option_map_;
/** /**
* Flags passed on the command-line. * Flags passed on the command-line.
@ -166,7 +179,7 @@ protected:
is_read_only_(is_read_only), is_read_only_(is_read_only),
is_key_hex_(false), is_key_hex_(false),
is_value_hex_(false), is_value_hex_(false),
options_(options), option_map_(options),
flags_(flags), flags_(flags),
valid_cmd_line_options_(valid_cmd_line_options) { valid_cmd_line_options_(valid_cmd_line_options) {
@ -180,19 +193,19 @@ protected:
} }
void OpenDB() { void OpenDB() {
leveldb::Options opt = PrepareOptionsForOpenDB(); Options opt = PrepareOptionsForOpenDB();
if (!exec_state_.IsNotStarted()) { if (!exec_state_.IsNotStarted()) {
return; return;
} }
// Open the DB. // Open the DB.
leveldb::Status st; Status st;
if (is_read_only_) { if (is_read_only_) {
st = leveldb::DB::OpenForReadOnly(opt, db_path_, &db_); st = DB::OpenForReadOnly(opt, db_path_, &db_);
} else { } else {
st = leveldb::DB::Open(opt, db_path_, &db_); st = DB::Open(opt, db_path_, &db_);
} }
if (!st.ok()) { if (!st.ok()) {
std::string msg = st.ToString(); string msg = st.ToString();
exec_state_ = LDBCommandExecuteResult::FAILED(msg); exec_state_ = LDBCommandExecuteResult::FAILED(msg);
} }
} }
@ -251,6 +264,8 @@ protected:
private: private:
Options options_;
/** /**
* Interpret command line options and flags to determine if the key * Interpret command line options and flags to determine if the key
* should be input/output in hex. * should be input/output in hex.
@ -308,6 +323,13 @@ private:
} }
} }
static LDBCommand* SelectCommand(
const string& cmd,
vector<string>& cmdParams,
map<string, string>& option_map,
vector<string>& flags
);
}; };
class CompactorCommand: public LDBCommand { class CompactorCommand: public LDBCommand {
@ -364,7 +386,7 @@ public:
static void Help(string& ret); static void Help(string& ret);
virtual void DoCommand(); virtual void DoCommand();
virtual leveldb::Options PrepareOptionsForOpenDB(); virtual Options PrepareOptionsForOpenDB();
private: private:
bool create_if_missing_; bool create_if_missing_;
@ -406,7 +428,7 @@ public:
ReduceDBLevelsCommand(const vector<string>& params, ReduceDBLevelsCommand(const vector<string>& params,
const map<string, string>& options, const vector<string>& flags); const map<string, string>& options, const vector<string>& flags);
virtual leveldb::Options PrepareOptionsForOpenDB(); virtual Options PrepareOptionsForOpenDB();
virtual void DoCommand(); virtual void DoCommand();
@ -427,7 +449,7 @@ private:
static const string ARG_NEW_LEVELS; static const string ARG_NEW_LEVELS;
static const string ARG_PRINT_OLD_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 { class WALDumperCommand : public LDBCommand {
@ -497,7 +519,7 @@ public:
static void Help(string& ret); static void Help(string& ret);
virtual leveldb::Options PrepareOptionsForOpenDB(); virtual Options PrepareOptionsForOpenDB();
private: private:
/** /**
@ -551,7 +573,7 @@ public:
static void Help(string& ret); static void Help(string& ret);
virtual leveldb::Options PrepareOptionsForOpenDB(); virtual Options PrepareOptionsForOpenDB();
private: private:
string key_; string key_;
@ -580,5 +602,5 @@ private:
static const char* DELETE_CMD; static const char* DELETE_CMD;
}; };
} } // namespace leveldb
#endif #endif // STORAGE_LEVELDB_UTIL_LDB_CMD_H_

@ -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 +
"=<full_path_to_db_directory> 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 + "=<int,e.g.:14>\n");
ret.append(" --" + LDBCommand::ARG_COMPRESSION_TYPE +
"=<no|snappy|zlib|bzip2>\n");
ret.append(" --" + LDBCommand::ARG_BLOCK_SIZE +
"=<block_size_in_bytes>\n");
ret.append(" --" + LDBCommand::ARG_AUTO_COMPACTION + "=<true|false>\n");
ret.append(" --" + LDBCommand::ARG_WRITE_BUFFER_SIZE +
"=<int,e.g.:4194304>\n");
ret.append(" --" + LDBCommand::ARG_FILE_SIZE + "=<int,e.g.:2097152>\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
Loading…
Cancel
Save