| // Copyright (c) 2013, 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). |
| // |
| #ifndef ROCKSDB_LITE |
| |
| #ifndef __STDC_FORMAT_MACROS |
| #define __STDC_FORMAT_MACROS |
| #endif |
| |
| #include "utilities/persistent_cache/persistent_cache_tier.h" |
| |
| #include "inttypes.h" |
| |
| #include <string> |
| #include <sstream> |
| |
| namespace rocksdb { |
| |
| std::string PersistentCacheConfig::ToString() const { |
| std::string ret; |
| ret.reserve(20000); |
| const int kBufferSize = 200; |
| char buffer[kBufferSize]; |
| |
| snprintf(buffer, kBufferSize, " path: %s\n", path.c_str()); |
| ret.append(buffer); |
| snprintf(buffer, kBufferSize, " enable_direct_reads: %d\n", |
| enable_direct_reads); |
| ret.append(buffer); |
| snprintf(buffer, kBufferSize, " enable_direct_writes: %d\n", |
| enable_direct_writes); |
| ret.append(buffer); |
| snprintf(buffer, kBufferSize, " cache_size: %" PRIu64 "\n", cache_size); |
| ret.append(buffer); |
| snprintf(buffer, kBufferSize, " cache_file_size: %" PRIu32 "\n", |
| cache_file_size); |
| ret.append(buffer); |
| snprintf(buffer, kBufferSize, " writer_qdepth: %" PRIu32 "\n", |
| writer_qdepth); |
| ret.append(buffer); |
| snprintf(buffer, kBufferSize, " pipeline_writes: %d\n", pipeline_writes); |
| ret.append(buffer); |
| snprintf(buffer, kBufferSize, |
| " max_write_pipeline_backlog_size: %" PRIu64 "\n", |
| max_write_pipeline_backlog_size); |
| ret.append(buffer); |
| snprintf(buffer, kBufferSize, " write_buffer_size: %" PRIu32 "\n", |
| write_buffer_size); |
| ret.append(buffer); |
| snprintf(buffer, kBufferSize, " writer_dispatch_size: %" PRIu64 "\n", |
| writer_dispatch_size); |
| ret.append(buffer); |
| snprintf(buffer, kBufferSize, " is_compressed: %d\n", is_compressed); |
| ret.append(buffer); |
| |
| return ret; |
| } |
| |
| // |
| // PersistentCacheTier implementation |
| // |
| Status PersistentCacheTier::Open() { |
| if (next_tier_) { |
| return next_tier_->Open(); |
| } |
| return Status::OK(); |
| } |
| |
| Status PersistentCacheTier::Close() { |
| if (next_tier_) { |
| return next_tier_->Close(); |
| } |
| return Status::OK(); |
| } |
| |
| bool PersistentCacheTier::Reserve(const size_t size) { |
| // default implementation is a pass through |
| return true; |
| } |
| |
| bool PersistentCacheTier::Erase(const Slice& key) { |
| // default implementation is a pass through since not all cache tiers might |
| // support erase |
| return true; |
| } |
| |
| std::string PersistentCacheTier::PrintStats() { |
| std::ostringstream os; |
| for (auto tier_stats : Stats()) { |
| os << "---- next tier -----" << std::endl; |
| for (auto stat : tier_stats) { |
| os << stat.first << ": " << stat.second << std::endl; |
| } |
| } |
| return os.str(); |
| } |
| |
| PersistentCache::StatsType PersistentCacheTier::Stats() { |
| if (next_tier_) { |
| return next_tier_->Stats(); |
| } |
| return PersistentCache::StatsType{}; |
| } |
| |
| // |
| // PersistentTieredCache implementation |
| // |
| PersistentTieredCache::~PersistentTieredCache() { assert(tiers_.empty()); } |
| |
| Status PersistentTieredCache::Open() { |
| assert(!tiers_.empty()); |
| return tiers_.front()->Open(); |
| } |
| |
| Status PersistentTieredCache::Close() { |
| assert(!tiers_.empty()); |
| Status status = tiers_.front()->Close(); |
| if (status.ok()) { |
| tiers_.clear(); |
| } |
| return status; |
| } |
| |
| bool PersistentTieredCache::Erase(const Slice& key) { |
| assert(!tiers_.empty()); |
| return tiers_.front()->Erase(key); |
| } |
| |
| PersistentCache::StatsType PersistentTieredCache::Stats() { |
| assert(!tiers_.empty()); |
| return tiers_.front()->Stats(); |
| } |
| |
| std::string PersistentTieredCache::PrintStats() { |
| assert(!tiers_.empty()); |
| return tiers_.front()->PrintStats(); |
| } |
| |
| Status PersistentTieredCache::Insert(const Slice& page_key, const char* data, |
| const size_t size) { |
| assert(!tiers_.empty()); |
| return tiers_.front()->Insert(page_key, data, size); |
| } |
| |
| Status PersistentTieredCache::Lookup(const Slice& page_key, |
| std::unique_ptr<char[]>* data, |
| size_t* size) { |
| assert(!tiers_.empty()); |
| return tiers_.front()->Lookup(page_key, data, size); |
| } |
| |
| void PersistentTieredCache::AddTier(const Tier& tier) { |
| if (!tiers_.empty()) { |
| tiers_.back()->set_next_tier(tier); |
| } |
| tiers_.push_back(tier); |
| } |
| |
| bool PersistentTieredCache::IsCompressed() { |
| assert(tiers_.size()); |
| return tiers_.front()->IsCompressed(); |
| } |
| |
| } // namespace rocksdb |
| |
| #endif |