Introduce a dedicated class to represent blob values (#10571)
Summary: The patch introduces a new class called `BlobContents`, which represents a single uncompressed blob value. We currently use `std::string` for this purpose; `BlobContents` is somewhat smaller but the primary reason for a dedicated class is that it enables certain improvements and optimizations like eliding a copy when inserting a blob into the cache, using custom allocators, or more control over and better accounting of the memory usage of cached blobs (see https://github.com/facebook/rocksdb/issues/10484). (We plan to implement these in subsequent PRs.) Pull Request resolved: https://github.com/facebook/rocksdb/pull/10571 Test Plan: `make check` Reviewed By: riversand963 Differential Revision: D39000965 Pulled By: ltamasi fbshipit-source-id: f296eddf9dec4fc3e11cad525b462bdf63c78f96main
parent
418b36a9bc
commit
3f57d84af4
@ -0,0 +1,63 @@ |
|||||||
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
|
// 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).
|
||||||
|
|
||||||
|
#include "db/blob/blob_contents.h" |
||||||
|
|
||||||
|
#include <cassert> |
||||||
|
|
||||||
|
#include "cache/cache_helpers.h" |
||||||
|
|
||||||
|
namespace ROCKSDB_NAMESPACE { |
||||||
|
|
||||||
|
std::unique_ptr<BlobContents> BlobContents::Create( |
||||||
|
CacheAllocationPtr&& allocation, size_t size) { |
||||||
|
return std::unique_ptr<BlobContents>( |
||||||
|
new BlobContents(std::move(allocation), size)); |
||||||
|
} |
||||||
|
|
||||||
|
size_t BlobContents::SizeCallback(void* obj) { |
||||||
|
assert(obj); |
||||||
|
|
||||||
|
return static_cast<const BlobContents*>(obj)->size(); |
||||||
|
} |
||||||
|
|
||||||
|
Status BlobContents::SaveToCallback(void* from_obj, size_t from_offset, |
||||||
|
size_t length, void* out) { |
||||||
|
assert(from_obj); |
||||||
|
|
||||||
|
const BlobContents* buf = static_cast<const BlobContents*>(from_obj); |
||||||
|
assert(buf->size() >= from_offset + length); |
||||||
|
|
||||||
|
memcpy(out, buf->data().data() + from_offset, length); |
||||||
|
|
||||||
|
return Status::OK(); |
||||||
|
} |
||||||
|
|
||||||
|
void BlobContents::DeleteCallback(const Slice& key, void* value) { |
||||||
|
DeleteCacheEntry<BlobContents>(key, value); |
||||||
|
} |
||||||
|
|
||||||
|
Cache::CacheItemHelper* BlobContents::GetCacheItemHelper() { |
||||||
|
static Cache::CacheItemHelper cache_helper(&SizeCallback, &SaveToCallback, |
||||||
|
&DeleteCallback); |
||||||
|
|
||||||
|
return &cache_helper; |
||||||
|
} |
||||||
|
|
||||||
|
Status BlobContents::CreateCallback(const void* buf, size_t size, |
||||||
|
void** out_obj, size_t* charge) { |
||||||
|
CacheAllocationPtr allocation(new char[size]); |
||||||
|
memcpy(allocation.get(), buf, size); |
||||||
|
|
||||||
|
std::unique_ptr<BlobContents> obj = Create(std::move(allocation), size); |
||||||
|
BlobContents* const contents = obj.release(); |
||||||
|
|
||||||
|
*out_obj = contents; |
||||||
|
*charge = contents->size(); |
||||||
|
|
||||||
|
return Status::OK(); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace ROCKSDB_NAMESPACE
|
@ -0,0 +1,56 @@ |
|||||||
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
|
// 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 <memory> |
||||||
|
|
||||||
|
#include "memory/memory_allocator.h" |
||||||
|
#include "rocksdb/cache.h" |
||||||
|
#include "rocksdb/rocksdb_namespace.h" |
||||||
|
#include "rocksdb/slice.h" |
||||||
|
#include "rocksdb/status.h" |
||||||
|
|
||||||
|
namespace ROCKSDB_NAMESPACE { |
||||||
|
|
||||||
|
// A class representing a single uncompressed value read from a blob file.
|
||||||
|
class BlobContents { |
||||||
|
public: |
||||||
|
static std::unique_ptr<BlobContents> Create(CacheAllocationPtr&& allocation, |
||||||
|
size_t size); |
||||||
|
|
||||||
|
BlobContents(const BlobContents&) = delete; |
||||||
|
BlobContents& operator=(const BlobContents&) = delete; |
||||||
|
|
||||||
|
BlobContents(BlobContents&&) = default; |
||||||
|
BlobContents& operator=(BlobContents&&) = default; |
||||||
|
|
||||||
|
~BlobContents() = default; |
||||||
|
|
||||||
|
const Slice& data() const { return data_; } |
||||||
|
size_t size() const { return data_.size(); } |
||||||
|
|
||||||
|
// Callbacks for secondary cache
|
||||||
|
static size_t SizeCallback(void* obj); |
||||||
|
|
||||||
|
static Status SaveToCallback(void* from_obj, size_t from_offset, |
||||||
|
size_t length, void* out); |
||||||
|
|
||||||
|
static void DeleteCallback(const Slice& key, void* value); |
||||||
|
|
||||||
|
static Cache::CacheItemHelper* GetCacheItemHelper(); |
||||||
|
|
||||||
|
static Status CreateCallback(const void* buf, size_t size, void** out_obj, |
||||||
|
size_t* charge); |
||||||
|
|
||||||
|
private: |
||||||
|
BlobContents(CacheAllocationPtr&& allocation, size_t size) |
||||||
|
: allocation_(std::move(allocation)), data_(allocation_.get(), size) {} |
||||||
|
|
||||||
|
CacheAllocationPtr allocation_; |
||||||
|
Slice data_; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace ROCKSDB_NAMESPACE
|
Loading…
Reference in new issue