]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/utilities/persistent_cache/volatile_tier_impl.cc
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).
8 #include "utilities/persistent_cache/volatile_tier_impl.h"
14 void VolatileCacheTier::DeleteCacheData(VolatileCacheTier::CacheData
* data
) {
19 VolatileCacheTier::~VolatileCacheTier() { index_
.Clear(&DeleteCacheData
); }
21 PersistentCache::StatsType
VolatileCacheTier::Stats() {
22 std::map
<std::string
, double> stat
;
23 stat
.insert({"persistent_cache.volatile_cache.hits",
24 static_cast<double>(stats_
.cache_hits_
)});
25 stat
.insert({"persistent_cache.volatile_cache.misses",
26 static_cast<double>(stats_
.cache_misses_
)});
27 stat
.insert({"persistent_cache.volatile_cache.inserts",
28 static_cast<double>(stats_
.cache_inserts_
)});
29 stat
.insert({"persistent_cache.volatile_cache.evicts",
30 static_cast<double>(stats_
.cache_evicts_
)});
31 stat
.insert({"persistent_cache.volatile_cache.hit_pct",
32 static_cast<double>(stats_
.CacheHitPct())});
33 stat
.insert({"persistent_cache.volatile_cache.miss_pct",
34 static_cast<double>(stats_
.CacheMissPct())});
36 auto out
= PersistentCacheTier::Stats();
41 Status
VolatileCacheTier::Insert(const Slice
& page_key
, const char* data
,
50 // check if we have overshot the limit, if so evict some space
51 while (size_
> max_size_
) {
53 // unable to evict data, we give up so we don't spike read
55 assert(size_
>= size
);
57 return Status::TryAgain("Unable to evict any data");
61 assert(size_
>= size
);
63 // insert order: LRU, followed by index
64 std::string
key(page_key
.data(), page_key
.size());
65 std::string
value(data
, size
);
66 std::unique_ptr
<CacheData
> cache_data(
67 new CacheData(std::move(key
), std::move(value
)));
68 bool ok
= index_
.Insert(cache_data
.get());
70 // decrement the size that we incremented ahead of time
71 assert(size_
>= size
);
73 // failed to insert to cache, block already in cache
74 return Status::TryAgain("key already exists in volatile cache");
78 stats_
.cache_inserts_
++;
82 Status
VolatileCacheTier::Lookup(const Slice
& page_key
,
83 std::unique_ptr
<char[]>* result
,
85 CacheData
key(std::move(page_key
.ToString()));
87 bool ok
= index_
.Find(&key
, &kv
);
90 result
->reset(new char[kv
->value
.size()]);
91 memcpy(result
->get(), kv
->value
.c_str(), kv
->value
.size());
92 *size
= kv
->value
.size();
93 // drop the reference on cache data
100 stats_
.cache_misses_
++;
103 return next_tier()->Lookup(page_key
, result
, size
);
106 return Status::NotFound("key not found in volatile cache");
109 bool VolatileCacheTier::Erase(const Slice
& /*key*/) {
110 assert(!"not supported");
114 bool VolatileCacheTier::Evict() {
115 CacheData
* edata
= index_
.Evict();
117 // not able to evict any object
121 stats_
.cache_evicts_
++;
123 // push the evicted object to the next level
125 next_tier()->Insert(Slice(edata
->key
), edata
->value
.c_str(),
126 edata
->value
.size());
129 // adjust size and destroy data
130 size_
-= edata
->value
.size();
136 } // namespace rocksdb