diff --git a/tools/ldb_cmd.cc b/tools/ldb_cmd.cc index 90b7886eea1d..efef28ad7627 100644 --- a/tools/ldb_cmd.cc +++ b/tools/ldb_cmd.cc @@ -26,6 +26,7 @@ #include "db/wide/wide_columns_helper.h" #include "db/write_batch_internal.h" #include "file/filename.h" +#include "ldb_cmd_impl.h" #include "rocksdb/cache.h" #include "rocksdb/experimental.h" #include "rocksdb/file_checksum.h" @@ -208,6 +209,9 @@ LDBCommand* LDBCommand::SelectCommand(const ParsedParams& parsed_params) { if (parsed_params.cmd == GetCommand::Name()) { return new GetCommand(parsed_params.cmd_params, parsed_params.option_map, parsed_params.flags); + } else if (parsed_params.cmd == MultiGetCommand::Name()) { + return new MultiGetCommand(parsed_params.cmd_params, + parsed_params.option_map, parsed_params.flags); } else if (parsed_params.cmd == GetEntityCommand::Name()) { return new GetEntityCommand(parsed_params.cmd_params, parsed_params.option_map, parsed_params.flags); @@ -2872,6 +2876,66 @@ void GetCommand::DoCommand() { // ---------------------------------------------------------------------------- +MultiGetCommand::MultiGetCommand( + const std::vector& params, + const std::map& options, + const std::vector& flags) + : LDBCommand(options, flags, true, + BuildCmdLineOptions({ARG_HEX, ARG_KEY_HEX, ARG_VALUE_HEX})) { + if (params.size() < 1) { + exec_state_ = LDBCommandExecuteResult::Failed( + "At least one must be specified for multi_get."); + } else { + for (size_t i = 0; i < params.size(); ++i) { + std::string key = params.at(i); + keys_.emplace_back(is_key_hex_ ? HexToString(key) : key); + } + } +} + +void MultiGetCommand::Help(std::string& ret) { + ret.append(" "); + ret.append(MultiGetCommand::Name()); + ret.append(" ..."); + ret.append(" [--" + ARG_TTL + "]"); + ret.append("\n"); +} + +void MultiGetCommand::DoCommand() { + if (!db_) { + assert(GetExecuteState().IsFailed()); + return; + } + size_t num_keys = keys_.size(); + std::vector key_slices; + std::vector values(num_keys); + std::vector statuses(num_keys); + for (const std::string& key : keys_) { + key_slices.emplace_back(key); + } + db_->MultiGet(ReadOptions(), GetCfHandle(), num_keys, key_slices.data(), + values.data(), statuses.data()); + + bool failed = false; + for (size_t i = 0; i < num_keys; ++i) { + if (statuses[i].ok()) { + fprintf(stdout, is_value_hex_ ? "0x%s\n" : "%s\n", + values[i].ToString(is_value_hex_).c_str()); + } else { + fprintf(stderr, "Status for key %s: %s\n", + (is_key_hex_ ? StringToHex(keys_[i]) : keys_[i]).c_str(), + statuses[i].ToString().c_str()); + failed = false; + } + } + if (failed) { + exec_state_ = + LDBCommandExecuteResult::Failed("one of the keys had non okay status"); + } +} + +// ---------------------------------------------------------------------------- + GetEntityCommand::GetEntityCommand( const std::vector& params, const std::map& options, diff --git a/tools/ldb_cmd_impl.h b/tools/ldb_cmd_impl.h index 2a396754dcb1..30384eba7bf7 100644 --- a/tools/ldb_cmd_impl.h +++ b/tools/ldb_cmd_impl.h @@ -403,6 +403,22 @@ class GetCommand : public LDBCommand { std::string key_; }; +class MultiGetCommand : public LDBCommand { + public: + static std::string Name() { return "multi_get"; } + + MultiGetCommand(const std::vector& params, + const std::map& options, + const std::vector& flags); + + void DoCommand() override; + + static void Help(std::string& ret); + + private: + std::vector keys_; +}; + class GetEntityCommand : public LDBCommand { public: static std::string Name() { return "get_entity"; }