[RocksDB] allow LDB tool to have customized key formatter

Summary: Currently ldb tool dump keys either in ascii format or hex format - neither is ideal if the key has a binary structure and is not readable in ascii. This diff also allows LDB tool to be customized in ways beyond DB options.

Test Plan: verify that key formatter works with some simple db with binary key.

Reviewers: sdong, ljin

Reviewed By: ljin

Subscribers: leveldb

Differential Revision: https://reviews.facebook.net/D19209
This commit is contained in:
Haobo Xu 2014-06-19 23:54:13 -07:00
parent 3b0dc76699
commit dfb31d152d
4 changed files with 60 additions and 16 deletions

View File

@ -4,13 +4,32 @@
// of patent rights can be found in the PATENTS file in the same directory. // of patent rights can be found in the PATENTS file in the same directory.
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
#pragma once #pragma once
#include <string>
#include "rocksdb/options.h" #include "rocksdb/options.h"
namespace rocksdb { namespace rocksdb {
// An interface for converting a slice to a readable string
class SliceFormatter {
public:
virtual ~SliceFormatter() {}
virtual std::string Format(const Slice& s) const = 0;
};
// Options for customizing ldb tool (beyond the DB Options)
struct LDBOptions {
// Create LDBOptions with default values for all fields
LDBOptions();
// Key formatter that converts a slice to a readable string.
// Default: Slice::ToString()
std::shared_ptr<SliceFormatter> key_formatter;
};
class LDBTool { class LDBTool {
public: public:
void Run(int argc, char** argv, Options = Options()); void Run(int argc, char** argv, Options db_options= Options(),
const LDBOptions& ldb_options = LDBOptions());
}; };
} // namespace rocksdb } // namespace rocksdb

View File

@ -50,13 +50,14 @@ const char* LDBCommand::DELIM = " ==> ";
LDBCommand* LDBCommand::InitFromCmdLineArgs( LDBCommand* LDBCommand::InitFromCmdLineArgs(
int argc, int argc,
char** argv, char** argv,
const Options& options const Options& options,
const LDBOptions& ldb_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, options); return InitFromCmdLineArgs(args, options, ldb_options);
} }
/** /**
@ -71,7 +72,8 @@ LDBCommand* LDBCommand::InitFromCmdLineArgs(
*/ */
LDBCommand* LDBCommand::InitFromCmdLineArgs( LDBCommand* LDBCommand::InitFromCmdLineArgs(
const vector<string>& args, const vector<string>& args,
const Options& options const Options& options,
const LDBOptions& ldb_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> option_map; map<string, string> option_map;
@ -115,7 +117,8 @@ LDBCommand* LDBCommand::InitFromCmdLineArgs(
); );
if (command) { if (command) {
command->SetOptions(options); command->SetDBOptions(options);
command->SetLDBOptions(ldb_options);
} }
return command; return command;
} }
@ -1619,7 +1622,7 @@ void ScanCommand::DoCommand() {
for ( ; for ( ;
it->Valid() && (!end_key_specified_ || it->key().ToString() < end_key_); it->Valid() && (!end_key_specified_ || it->key().ToString() < end_key_);
it->Next()) { it->Next()) {
string key = it->key().ToString(); string key = ldb_options_.key_formatter->Format(it->key());
if (is_db_ttl_) { if (is_db_ttl_) {
TtlIterator* it_ttl = dynamic_cast<TtlIterator*>(it); TtlIterator* it_ttl = dynamic_cast<TtlIterator*>(it);
assert(it_ttl); assert(it_ttl);
@ -1633,8 +1636,8 @@ void ScanCommand::DoCommand() {
} }
string value = it->value().ToString(); string value = it->value().ToString();
fprintf(stdout, "%s : %s\n", fprintf(stdout, "%s : %s\n",
(is_key_hex_ ? StringToHex(key) : key).c_str(), (is_key_hex_ ? "0x" + it->key().ToString(true) : key).c_str(),
(is_value_hex_ ? StringToHex(value) : value).c_str() (is_value_hex_ ? StringToHex(value) : value).c_str()
); );
num_keys_scanned++; num_keys_scanned++;
if (max_keys_scanned_ >= 0 && num_keys_scanned >= max_keys_scanned_) { if (max_keys_scanned_ >= 0 && num_keys_scanned >= max_keys_scanned_) {

View File

@ -13,8 +13,9 @@
#include "db/version_set.h" #include "db/version_set.h"
#include "rocksdb/env.h" #include "rocksdb/env.h"
#include "rocksdb/options.h"
#include "rocksdb/iterator.h" #include "rocksdb/iterator.h"
#include "rocksdb/ldb_tool.h"
#include "rocksdb/options.h"
#include "rocksdb/slice.h" #include "rocksdb/slice.h"
#include "util/logging.h" #include "util/logging.h"
#include "util/ldb_cmd_execute_result.h" #include "util/ldb_cmd_execute_result.h"
@ -54,23 +55,29 @@ public:
static LDBCommand* InitFromCmdLineArgs( static LDBCommand* InitFromCmdLineArgs(
const vector<string>& args, const vector<string>& args,
const Options& options = Options() const Options& options,
const LDBOptions& ldb_options
); );
static LDBCommand* InitFromCmdLineArgs( static LDBCommand* InitFromCmdLineArgs(
int argc, int argc,
char** argv, char** argv,
const Options& options = Options() const Options& options,
const LDBOptions& ldb_options
); );
bool ValidateCmdLineOptions(); bool ValidateCmdLineOptions();
virtual Options PrepareOptionsForOpenDB(); virtual Options PrepareOptionsForOpenDB();
virtual void SetOptions(Options options) { virtual void SetDBOptions(Options options) {
options_ = options; options_ = options;
} }
void SetLDBOptions(const LDBOptions& ldb_options) {
ldb_options_ = ldb_options;
}
virtual bool NoDBOpen() { virtual bool NoDBOpen() {
return false; return false;
} }
@ -291,6 +298,7 @@ protected:
const string& option, string* value); const string& option, string* value);
Options options_; Options options_;
LDBOptions ldb_options_;
private: private:

View File

@ -9,6 +9,17 @@
namespace rocksdb { namespace rocksdb {
class DefaultSliceFormatter : public SliceFormatter {
public:
virtual std::string Format(const Slice& s) const override {
return s.ToString();
}
};
LDBOptions::LDBOptions()
: key_formatter(new DefaultSliceFormatter()) {
}
class LDBCommandRunner { class LDBCommandRunner {
public: public:
@ -71,13 +82,15 @@ public:
fprintf(stderr, "%s\n", ret.c_str()); fprintf(stderr, "%s\n", ret.c_str());
} }
static void RunCommand(int argc, char** argv, Options options) { static void RunCommand(int argc, char** argv, Options options,
const LDBOptions& ldb_options) {
if (argc <= 2) { if (argc <= 2) {
PrintHelp(argv[0]); PrintHelp(argv[0]);
exit(1); exit(1);
} }
LDBCommand* cmdObj = LDBCommand::InitFromCmdLineArgs(argc, argv, options); LDBCommand* cmdObj = LDBCommand::InitFromCmdLineArgs(argc, argv, options,
ldb_options);
if (cmdObj == nullptr) { if (cmdObj == nullptr) {
fprintf(stderr, "Unknown command\n"); fprintf(stderr, "Unknown command\n");
PrintHelp(argv[0]); PrintHelp(argv[0]);
@ -99,8 +112,9 @@ public:
}; };
void LDBTool::Run(int argc, char** argv, Options options) { void LDBTool::Run(int argc, char** argv, Options options,
LDBCommandRunner::RunCommand(argc, argv, options); const LDBOptions& ldb_options) {
LDBCommandRunner::RunCommand(argc, argv, options, ldb_options);
} }
} // namespace rocksdb } // namespace rocksdb