From 05dab3aacd877ca6ef500ac1f46efbbd0774cb27 Mon Sep 17 00:00:00 2001 From: Yi Wu Date: Tue, 13 Nov 2018 12:46:35 -0800 Subject: [PATCH] BlobDB: use char array instead of string as buffer (#4662) Summary: As pointed out in #4059, we miss use string as buffer for file read. Changing to use char array instead. Closing #4059 Pull Request resolved: https://github.com/facebook/rocksdb/pull/4662 Differential Revision: D13012998 Pulled By: yiwu-arbug fbshipit-source-id: 41234ba17c0bccea65bd647e362a0e979152bd1e --- utilities/blob_db/blob_log_format.h | 6 ++++-- utilities/blob_db/blob_log_reader.cc | 19 +++++++++++-------- utilities/blob_db/blob_log_reader.h | 6 +++--- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/utilities/blob_db/blob_log_format.h b/utilities/blob_db/blob_log_format.h index 3e1b686aa..fcc042f06 100644 --- a/utilities/blob_db/blob_log_format.h +++ b/utilities/blob_db/blob_log_format.h @@ -10,7 +10,9 @@ #ifndef ROCKSDB_LITE #include +#include #include + #include "rocksdb/options.h" #include "rocksdb/slice.h" #include "rocksdb/status.h" @@ -106,8 +108,8 @@ struct BlobLogRecord { uint32_t blob_crc = 0; Slice key; Slice value; - std::string key_buf; - std::string value_buf; + std::unique_ptr key_buf; + std::unique_ptr value_buf; uint64_t record_size() const { return kHeaderSize + key_size + value_size; } diff --git a/utilities/blob_db/blob_log_reader.cc b/utilities/blob_db/blob_log_reader.cc index 4996d987b..0f098f2d4 100644 --- a/utilities/blob_db/blob_log_reader.cc +++ b/utilities/blob_db/blob_log_reader.cc @@ -24,10 +24,9 @@ Reader::Reader(unique_ptr&& file_reader, Env* env, buffer_(), next_byte_(0) {} -Status Reader::ReadSlice(uint64_t size, Slice* slice, std::string* buf) { +Status Reader::ReadSlice(uint64_t size, Slice* slice, char* buf) { StopWatch read_sw(env_, statistics_, BLOB_DB_BLOB_FILE_READ_MICROS); - buf->reserve(static_cast(size)); - Status s = file_->Read(next_byte_, static_cast(size), slice, &(*buf)[0]); + Status s = file_->Read(next_byte_, static_cast(size), slice, buf); next_byte_ += size; if (!s.ok()) { return s; @@ -42,7 +41,7 @@ Status Reader::ReadSlice(uint64_t size, Slice* slice, std::string* buf) { Status Reader::ReadHeader(BlobLogHeader* header) { assert(file_.get() != nullptr); assert(next_byte_ == 0); - Status s = ReadSlice(BlobLogHeader::kSize, &buffer_, &backing_store_); + Status s = ReadSlice(BlobLogHeader::kSize, &buffer_, header_buf_); if (!s.ok()) { return s; } @@ -56,7 +55,7 @@ Status Reader::ReadHeader(BlobLogHeader* header) { Status Reader::ReadRecord(BlobLogRecord* record, ReadLevel level, uint64_t* blob_offset) { - Status s = ReadSlice(BlobLogRecord::kHeaderSize, &buffer_, &backing_store_); + Status s = ReadSlice(BlobLogRecord::kHeaderSize, &buffer_, header_buf_); if (!s.ok()) { return s; } @@ -80,14 +79,18 @@ Status Reader::ReadRecord(BlobLogRecord* record, ReadLevel level, break; case kReadHeaderKey: - s = ReadSlice(record->key_size, &record->key, &record->key_buf); + record->key_buf.reset(new char[record->key_size]); + s = ReadSlice(record->key_size, &record->key, record->key_buf.get()); next_byte_ += record->value_size; break; case kReadHeaderKeyBlob: - s = ReadSlice(record->key_size, &record->key, &record->key_buf); + record->key_buf.reset(new char[record->key_size]); + s = ReadSlice(record->key_size, &record->key, record->key_buf.get()); if (s.ok()) { - s = ReadSlice(record->value_size, &record->value, &record->value_buf); + record->value_buf.reset(new char[record->value_size]); + s = ReadSlice(record->value_size, &record->value, + record->value_buf.get()); } if (s.ok()) { s = record->CheckBlobCRC(); diff --git a/utilities/blob_db/blob_log_reader.h b/utilities/blob_db/blob_log_reader.h index 4b780decd..45e2e9551 100644 --- a/utilities/blob_db/blob_log_reader.h +++ b/utilities/blob_db/blob_log_reader.h @@ -60,19 +60,19 @@ class Reader { Status ReadRecord(BlobLogRecord* record, ReadLevel level = kReadHeader, uint64_t* blob_offset = nullptr); - Status ReadSlice(uint64_t size, Slice* slice, std::string* buf); - void ResetNextByte() { next_byte_ = 0; } uint64_t GetNextByte() const { return next_byte_; } private: + Status ReadSlice(uint64_t size, Slice* slice, char* buf); + const std::unique_ptr file_; Env* env_; Statistics* statistics_; - std::string backing_store_; Slice buffer_; + char header_buf_[BlobLogRecord::kHeaderSize]; // which byte to read next. For asserting proper usage uint64_t next_byte_;