mirror of
https://github.com/facebook/rocksdb.git
synced 2024-11-28 15:33:54 +00:00
fe56cb9aa0
Summary: Historically, `BlobFileReader` has returned the blob(s) read from the file in the `PinnableSlice` provided by the client. This interface was preserved when caching was implemented for blobs, which meant that the blob data was copied multiple times when caching was in use: first, into the client-provided `PinnableSlice` (by `BlobFileReader::SaveValue`), and then, into the object stored in the cache (by `BlobSource::PutBlobIntoCache`). The patch eliminates these copies and the related allocations by changing `BlobFileReader` so it returns its results in the form of heap-allocated `BlobContents` objects that can be directly inserted into the cache. The allocations backing these `BlobContents` objects are made using the blob cache's allocator if the blobs are to be inserted into the cache (i.e. if a cache is configured and the `fill_cache` read option is set). Note: this PR focuses on the common case when blobs are compressed; some further small optimizations are possible for uncompressed blobs. Pull Request resolved: https://github.com/facebook/rocksdb/pull/10647 Test Plan: `make check` Reviewed By: riversand963 Differential Revision: D39335185 Pulled By: ltamasi fbshipit-source-id: 464503d60a5520d654c8273ffb8efd5d1bcd7b36
109 lines
4.1 KiB
C++
109 lines
4.1 KiB
C++
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
// (found in the LICENSE.Apache file in the root directory).
|
|
|
|
#pragma once
|
|
|
|
#include <cinttypes>
|
|
#include <memory>
|
|
|
|
#include "db/blob/blob_read_request.h"
|
|
#include "file/random_access_file_reader.h"
|
|
#include "rocksdb/compression_type.h"
|
|
#include "rocksdb/rocksdb_namespace.h"
|
|
#include "util/autovector.h"
|
|
|
|
namespace ROCKSDB_NAMESPACE {
|
|
|
|
class Status;
|
|
struct ImmutableOptions;
|
|
struct FileOptions;
|
|
class HistogramImpl;
|
|
struct ReadOptions;
|
|
class Slice;
|
|
class FilePrefetchBuffer;
|
|
class BlobContents;
|
|
class Statistics;
|
|
|
|
class BlobFileReader {
|
|
public:
|
|
static Status Create(const ImmutableOptions& immutable_options,
|
|
const FileOptions& file_options,
|
|
uint32_t column_family_id,
|
|
HistogramImpl* blob_file_read_hist,
|
|
uint64_t blob_file_number,
|
|
const std::shared_ptr<IOTracer>& io_tracer,
|
|
std::unique_ptr<BlobFileReader>* reader);
|
|
|
|
BlobFileReader(const BlobFileReader&) = delete;
|
|
BlobFileReader& operator=(const BlobFileReader&) = delete;
|
|
|
|
~BlobFileReader();
|
|
|
|
Status GetBlob(const ReadOptions& read_options, const Slice& user_key,
|
|
uint64_t offset, uint64_t value_size,
|
|
CompressionType compression_type,
|
|
FilePrefetchBuffer* prefetch_buffer,
|
|
MemoryAllocator* allocator,
|
|
std::unique_ptr<BlobContents>* result,
|
|
uint64_t* bytes_read) const;
|
|
|
|
// offsets must be sorted in ascending order by caller.
|
|
void MultiGetBlob(
|
|
const ReadOptions& read_options, MemoryAllocator* allocator,
|
|
autovector<std::pair<BlobReadRequest*, std::unique_ptr<BlobContents>>>&
|
|
blob_reqs,
|
|
uint64_t* bytes_read) const;
|
|
|
|
CompressionType GetCompressionType() const { return compression_type_; }
|
|
|
|
uint64_t GetFileSize() const { return file_size_; }
|
|
|
|
private:
|
|
BlobFileReader(std::unique_ptr<RandomAccessFileReader>&& file_reader,
|
|
uint64_t file_size, CompressionType compression_type,
|
|
SystemClock* clock, Statistics* statistics);
|
|
|
|
static Status OpenFile(const ImmutableOptions& immutable_options,
|
|
const FileOptions& file_opts,
|
|
HistogramImpl* blob_file_read_hist,
|
|
uint64_t blob_file_number,
|
|
const std::shared_ptr<IOTracer>& io_tracer,
|
|
uint64_t* file_size,
|
|
std::unique_ptr<RandomAccessFileReader>* file_reader);
|
|
|
|
static Status ReadHeader(const RandomAccessFileReader* file_reader,
|
|
uint32_t column_family_id, Statistics* statistics,
|
|
CompressionType* compression_type);
|
|
|
|
static Status ReadFooter(const RandomAccessFileReader* file_reader,
|
|
uint64_t file_size, Statistics* statistics);
|
|
|
|
using Buffer = std::unique_ptr<char[]>;
|
|
|
|
static Status ReadFromFile(const RandomAccessFileReader* file_reader,
|
|
uint64_t read_offset, size_t read_size,
|
|
Statistics* statistics, Slice* slice, Buffer* buf,
|
|
AlignedBuf* aligned_buf,
|
|
Env::IOPriority rate_limiter_priority);
|
|
|
|
static Status VerifyBlob(const Slice& record_slice, const Slice& user_key,
|
|
uint64_t value_size);
|
|
|
|
static Status UncompressBlobIfNeeded(const Slice& value_slice,
|
|
CompressionType compression_type,
|
|
MemoryAllocator* allocator,
|
|
SystemClock* clock,
|
|
Statistics* statistics,
|
|
std::unique_ptr<BlobContents>* result);
|
|
|
|
std::unique_ptr<RandomAccessFileReader> file_reader_;
|
|
uint64_t file_size_;
|
|
CompressionType compression_type_;
|
|
SystemClock* clock_;
|
|
Statistics* statistics_;
|
|
};
|
|
|
|
} // namespace ROCKSDB_NAMESPACE
|