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