From dfb31d152d54cd3ea8192640141389448e571b64 Mon Sep 17 00:00:00 2001 From: Haobo Xu Date: Thu, 19 Jun 2014 23:54:13 -0700 Subject: [PATCH] [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 --- include/rocksdb/ldb_tool.h | 21 ++++++++++++++++++++- util/ldb_cmd.cc | 17 ++++++++++------- util/ldb_cmd.h | 16 ++++++++++++---- util/ldb_tool.cc | 22 ++++++++++++++++++---- 4 files changed, 60 insertions(+), 16 deletions(-) diff --git a/include/rocksdb/ldb_tool.h b/include/rocksdb/ldb_tool.h index 46bacc806..1b1c64b06 100644 --- a/include/rocksdb/ldb_tool.h +++ b/include/rocksdb/ldb_tool.h @@ -4,13 +4,32 @@ // of patent rights can be found in the PATENTS file in the same directory. #ifndef ROCKSDB_LITE #pragma once +#include #include "rocksdb/options.h" 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 key_formatter; +}; + class LDBTool { 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 diff --git a/util/ldb_cmd.cc b/util/ldb_cmd.cc index 597179fd9..e623e5278 100644 --- a/util/ldb_cmd.cc +++ b/util/ldb_cmd.cc @@ -50,13 +50,14 @@ const char* LDBCommand::DELIM = " ==> "; LDBCommand* LDBCommand::InitFromCmdLineArgs( int argc, char** argv, - const Options& options + const Options& options, + const LDBOptions& ldb_options ) { vector args; for (int i = 1; i < argc; 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( const vector& args, - const Options& options + const Options& options, + const LDBOptions& ldb_options ) { // --x=y command line arguments are added as x->y map entries. map option_map; @@ -115,7 +117,8 @@ LDBCommand* LDBCommand::InitFromCmdLineArgs( ); if (command) { - command->SetOptions(options); + command->SetDBOptions(options); + command->SetLDBOptions(ldb_options); } return command; } @@ -1619,7 +1622,7 @@ void ScanCommand::DoCommand() { for ( ; it->Valid() && (!end_key_specified_ || it->key().ToString() < end_key_); it->Next()) { - string key = it->key().ToString(); + string key = ldb_options_.key_formatter->Format(it->key()); if (is_db_ttl_) { TtlIterator* it_ttl = dynamic_cast(it); assert(it_ttl); @@ -1633,8 +1636,8 @@ void ScanCommand::DoCommand() { } string value = it->value().ToString(); fprintf(stdout, "%s : %s\n", - (is_key_hex_ ? StringToHex(key) : key).c_str(), - (is_value_hex_ ? StringToHex(value) : value).c_str() + (is_key_hex_ ? "0x" + it->key().ToString(true) : key).c_str(), + (is_value_hex_ ? StringToHex(value) : value).c_str() ); num_keys_scanned++; if (max_keys_scanned_ >= 0 && num_keys_scanned >= max_keys_scanned_) { diff --git a/util/ldb_cmd.h b/util/ldb_cmd.h index 4f760e0ce..50dcbf929 100644 --- a/util/ldb_cmd.h +++ b/util/ldb_cmd.h @@ -13,8 +13,9 @@ #include "db/version_set.h" #include "rocksdb/env.h" -#include "rocksdb/options.h" #include "rocksdb/iterator.h" +#include "rocksdb/ldb_tool.h" +#include "rocksdb/options.h" #include "rocksdb/slice.h" #include "util/logging.h" #include "util/ldb_cmd_execute_result.h" @@ -54,23 +55,29 @@ public: static LDBCommand* InitFromCmdLineArgs( const vector& args, - const Options& options = Options() + const Options& options, + const LDBOptions& ldb_options ); static LDBCommand* InitFromCmdLineArgs( int argc, char** argv, - const Options& options = Options() + const Options& options, + const LDBOptions& ldb_options ); bool ValidateCmdLineOptions(); virtual Options PrepareOptionsForOpenDB(); - virtual void SetOptions(Options options) { + virtual void SetDBOptions(Options options) { options_ = options; } + void SetLDBOptions(const LDBOptions& ldb_options) { + ldb_options_ = ldb_options; + } + virtual bool NoDBOpen() { return false; } @@ -291,6 +298,7 @@ protected: const string& option, string* value); Options options_; + LDBOptions ldb_options_; private: diff --git a/util/ldb_tool.cc b/util/ldb_tool.cc index 8439b63f9..271dba350 100644 --- a/util/ldb_tool.cc +++ b/util/ldb_tool.cc @@ -9,6 +9,17 @@ 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 { public: @@ -71,13 +82,15 @@ public: 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) { PrintHelp(argv[0]); exit(1); } - LDBCommand* cmdObj = LDBCommand::InitFromCmdLineArgs(argc, argv, options); + LDBCommand* cmdObj = LDBCommand::InitFromCmdLineArgs(argc, argv, options, + ldb_options); if (cmdObj == nullptr) { fprintf(stderr, "Unknown command\n"); PrintHelp(argv[0]); @@ -99,8 +112,9 @@ public: }; -void LDBTool::Run(int argc, char** argv, Options options) { - LDBCommandRunner::RunCommand(argc, argv, options); +void LDBTool::Run(int argc, char** argv, Options options, + const LDBOptions& ldb_options) { + LDBCommandRunner::RunCommand(argc, argv, options, ldb_options); } } // namespace rocksdb