store{store}
{}
-seastar::future<object_info_t> PGBackend::get_object(const hobject_t& oid)
+seastar::future<PGBackend::cached_oi_t>
+PGBackend::get_object(const hobject_t& oid)
{
// want the head?
if (oid.snap == CEPH_NOSNAP) {
return _load_oi(oid);
} else {
// we want a snap
- return _load_ss(oid).then([oid,this](SnapSet ss) {
+ return _load_ss(oid).then([oid,this](cached_ss_t ss) {
// head?
- if (oid.snap > ss.seq) {
+ if (oid.snap > ss->seq) {
return _load_oi(oid.get_head());
} else {
// which clone would it be?
- auto clone = std::upper_bound(begin(ss.clones), end(ss.clones),
+ auto clone = std::upper_bound(begin(ss->clones), end(ss->clones),
oid.snap);
- if (clone == end(ss.clones)) {
+ if (clone == end(ss->clones)) {
throw object_not_found{};
}
// clone
auto soid = oid;
soid.snap = *clone;
- return _load_ss(soid).then([soid,this](SnapSet ss) {
- auto clone_snap = ss.clone_snaps.find(soid.snap);
- assert(clone_snap != end(ss.clone_snaps));
+ return _load_ss(soid).then([soid,this](cached_ss_t ss) {
+ auto clone_snap = ss->clone_snaps.find(soid.snap);
+ assert(clone_snap != end(ss->clone_snaps));
if (clone_snap->second.empty()) {
logger().trace("find_object: {}@[] -- DNE", soid);
throw object_not_found{};
}
}
-seastar::future<object_info_t> PGBackend::_load_oi(const hobject_t& oid)
+seastar::future<PGBackend::cached_oi_t>
+PGBackend::_load_oi(const hobject_t& oid)
{
+ if (auto found = oi_cache.find(oid); found) {
+ return seastar::make_ready_future<cached_oi_t>(std::move(found));
+ }
return store->get_attr(coll,
ghobject_t{oid, ghobject_t::NO_GEN, shard},
- OI_ATTR).then([this](auto bp) {
- object_info_t oi;
+ OI_ATTR).then([oid, this](auto bp) {
+ auto oi = std::make_unique<object_info_t>();
bufferlist bl;
bl.push_back(std::move(bp));
- oi.decode(bl);
- return seastar::make_ready_future<object_info_t>(std::move(oi));
+ oi->decode(bl);
+ return seastar::make_ready_future<cached_oi_t>(
+ oi_cache.insert(oid, std::move(oi)));
});
}
-seastar::future<SnapSet> PGBackend::_load_ss(const hobject_t& oid)
+seastar::future<PGBackend::cached_ss_t>
+PGBackend::_load_ss(const hobject_t& oid)
{
+ if (auto found = ss_cache.find(oid); found) {
+ return seastar::make_ready_future<cached_ss_t>(std::move(found));
+ }
return store->get_attr(coll,
ghobject_t{oid, ghobject_t::NO_GEN, shard},
- SS_ATTR).then([this](auto bp) {
+ SS_ATTR).then([oid, this](auto bp) {
bufferlist bl;
bl.push_back(std::move(bp));
- SnapSet snapset{bl};
- return seastar::make_ready_future<SnapSet>(std::move(snapset));
+ auto snapset = std::make_unique<SnapSet>(bl);
+ return seastar::make_ready_future<cached_ss_t>(
+ ss_cache.insert(oid, std::move(snapset)));
});
}
#include <map>
#include <memory>
#include <string>
+#include <boost/smart_ptr/local_shared_ptr.hpp>
+#include "crimson/common/shared_lru.h"
#include "osd/osd_types.h"
struct hobject_t;
const pg_pool_t& pool,
ceph::os::CyanStore* store,
const ec_profile_t& ec_profile);
- seastar::future<object_info_t> get_object(const hobject_t& oid);
+ using cached_oi_t = boost::local_shared_ptr<object_info_t>;
+ seastar::future<cached_oi_t> get_object(const hobject_t& oid);
seastar::future<bufferlist> read(const object_info_t& oi,
uint64_t off,
uint64_t len,
ceph::os::CyanStore* store;
private:
- seastar::future<SnapSet> _load_ss(const hobject_t& oid);
- seastar::future<object_info_t> _load_oi(const hobject_t& oid);
+ using cached_ss_t = boost::local_shared_ptr<SnapSet>;
+ SharedLRU<hobject_t, SnapSet> ss_cache;
+ seastar::future<cached_ss_t> _load_ss(const hobject_t& oid);
+ SharedLRU<hobject_t, object_info_t> oi_cache;
+ seastar::future<cached_oi_t> _load_oi(const hobject_t& oid);
virtual seastar::future<bufferlist> _read(const hobject_t& hoid,
size_t offset,
size_t length,