1 //  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 //
6 #ifndef ROCKSDB_LITE
7 
8 #include "utilities/persistent_cache/persistent_cache_tier.h"
9 
10 #include <cinttypes>
11 #include <sstream>
12 #include <string>
13 
14 namespace ROCKSDB_NAMESPACE {
15 
16 std::string PersistentCacheConfig::ToString() const {
audio_file_new(audio_file ** f,const char * filename,gboolean editable)17   std::string ret;
18   ret.reserve(20000);
19   const int kBufferSize = 200;
20   char buffer[kBufferSize];
21 
22   snprintf(buffer, kBufferSize, "    path: %s\n", path.c_str());
23   ret.append(buffer);
24   snprintf(buffer, kBufferSize, "    enable_direct_reads: %d\n",
25            enable_direct_reads);
26   ret.append(buffer);
27   snprintf(buffer, kBufferSize, "    enable_direct_writes: %d\n",
28            enable_direct_writes);
29   ret.append(buffer);
30   snprintf(buffer, kBufferSize, "    cache_size: %" PRIu64 "\n", cache_size);
31   ret.append(buffer);
32   snprintf(buffer, kBufferSize, "    cache_file_size: %" PRIu32 "\n",
33            cache_file_size);
audio_file_get_name(audio_file * f)34   ret.append(buffer);
35   snprintf(buffer, kBufferSize, "    writer_qdepth: %" PRIu32 "\n",
36            writer_qdepth);
37   ret.append(buffer);
38   snprintf(buffer, kBufferSize, "    pipeline_writes: %d\n", pipeline_writes);
audio_file_get_extension(audio_file * f)39   ret.append(buffer);
40   snprintf(buffer, kBufferSize,
41            "    max_write_pipeline_backlog_size: %" PRIu64 "\n",
42            max_write_pipeline_backlog_size);
43   ret.append(buffer);
44   snprintf(buffer, kBufferSize, "    write_buffer_size: %" PRIu32 "\n",
45            write_buffer_size);
46   ret.append(buffer);
47   snprintf(buffer, kBufferSize, "    writer_dispatch_size: %" PRIu64 "\n",
48            writer_dispatch_size);
49   ret.append(buffer);
audio_file_is_editable(audio_file * f)50   snprintf(buffer, kBufferSize, "    is_compressed: %d\n", is_compressed);
51   ret.append(buffer);
52 
53   return ret;
54 }
audio_file_has_changes(audio_file * f)55 
56 //
57 // PersistentCacheTier implementation
58 //
59 Status PersistentCacheTier::Open() {
60   if (next_tier_) {
61     return next_tier_->Open();
62   }
63   return Status::OK();
64 }
65 
audio_file_delete(audio_file * f)66 Status PersistentCacheTier::Close() {
67   if (next_tier_) {
68     return next_tier_->Close();
69   }
70   return Status::OK();
71 }
72 
73 bool PersistentCacheTier::Reserve(const size_t /*size*/) {
74   // default implementation is a pass through
75   return true;
audio_file_get_info(audio_file * f)76 }
77 
78 bool PersistentCacheTier::Erase(const Slice& /*key*/) {
79   // default implementation is a pass through since not all cache tiers might
80   // support erase
81   return true;
82 }
83 
84 std::string PersistentCacheTier::PrintStats() {
85   std::ostringstream os;
audio_file_create_tag(audio_file * f)86   for (auto tier_stats : Stats()) {
87     os << "---- next tier -----" << std::endl;
88     for (auto stat : tier_stats) {
89       os << stat.first << ": " << stat.second << std::endl;
90     }
91   }
92   return os.str();
93 }
94 
95 PersistentCache::StatsType PersistentCacheTier::Stats() {
audio_file_write_changes(audio_file * f)96   if (next_tier_) {
97     return next_tier_->Stats();
98   }
99   return PersistentCache::StatsType{};
100 }
audio_file_set_field(audio_file * f,int field,const char * value)101 
102 //
103 // PersistentTieredCache implementation
104 //
105 PersistentTieredCache::~PersistentTieredCache() { assert(tiers_.empty()); }
audio_file_get_field(audio_file * f,int field,const char ** value)106 
107 Status PersistentTieredCache::Open() {
108   assert(!tiers_.empty());
109   return tiers_.front()->Open();
110 }
audio_file_dump(audio_file * f)111 
112 Status PersistentTieredCache::Close() {
113   assert(!tiers_.empty());
114   Status status = tiers_.front()->Close();
115   if (status.ok()) {
116     tiers_.clear();
117   }
118   return status;
119 }
120 
audio_file_edit_unload(audio_file * f)121 bool PersistentTieredCache::Erase(const Slice& key) {
122   assert(!tiers_.empty());
123   return tiers_.front()->Erase(key);
124 }
125 
126 PersistentCache::StatsType PersistentTieredCache::Stats() {
127   assert(!tiers_.empty());
128   return tiers_.front()->Stats();
129 }
130 
131 std::string PersistentTieredCache::PrintStats() {
132   assert(!tiers_.empty());
133   return tiers_.front()->PrintStats();
134 }
135 
136 Status PersistentTieredCache::Insert(const Slice& page_key, const char* data,
137                                      const size_t size) {
138   assert(!tiers_.empty());
139   return tiers_.front()->Insert(page_key, data, size);
140 }
141 
142 Status PersistentTieredCache::Lookup(const Slice& page_key,
143                                      std::unique_ptr<char[]>* data,
144                                      size_t* size) {
145   assert(!tiers_.empty());
146   return tiers_.front()->Lookup(page_key, data, size);
147 }
148 
149 void PersistentTieredCache::AddTier(const Tier& tier) {
150   if (!tiers_.empty()) {
151     tiers_.back()->set_next_tier(tier);
152   }
153   tiers_.push_back(tier);
154 }
155 
156 bool PersistentTieredCache::IsCompressed() {
157   assert(tiers_.size());
158   return tiers_.front()->IsCompressed();
159 }
160 
161 }  // namespace ROCKSDB_NAMESPACE
162 
163 #endif
164