From 6cd689cf2e8734d84f46d7cdb075c7a7755693ee Mon Sep 17 00:00:00 2001 From: Joao Eduardo Luis Date: Sat, 3 Jun 2023 10:25:19 +0000 Subject: [PATCH] rgw/sfs: update bucket stats Signed-off-by: Joao Eduardo Luis --- src/rgw/driver/sfs/bucket.cc | 29 ++++++++++++++++++- src/rgw/driver/sfs/sqlite/sqlite_buckets.cc | 32 +++++++++++++++++++++ src/rgw/driver/sfs/sqlite/sqlite_buckets.h | 8 ++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/rgw/driver/sfs/bucket.cc b/src/rgw/driver/sfs/bucket.cc index 01db2a73e1eff3..93e906ad3db2c4 100644 --- a/src/rgw/driver/sfs/bucket.cc +++ b/src/rgw/driver/sfs/bucket.cc @@ -599,9 +599,36 @@ int SFSBucket::sync_user_stats( ) { return 0; } -int SFSBucket::update_container_stats(const DoutPrefixProvider* /*dpp*/) { + +int SFSBucket::update_container_stats(const DoutPrefixProvider* dpp) { + lsfs_dout(dpp, 10) << fmt::format( + "update bucket {} (id {}) stats", get_name(), + get_bucket_id() + ) + << dendl; + sfs::sqlite::SQLiteBuckets bucketdb(store->db_conn); + auto stats = bucketdb.get_stats(get_bucket_id()); + + if (!stats.has_value()) { + lsfs_dout(dpp, 10) << fmt::format( + "unable to obtain stats for bucket {} (id {}) -- " + "no such bucket!", + get_name(), get_bucket_id() + ) + << dendl; + return -ERR_NO_SUCH_BUCKET; + } + + lsfs_dout(dpp, 10) << fmt::format( + "bucket {} stats: size: {}, obj_cnt: {}", + get_name(), stats->size, stats->obj_count + ) + << dendl; + ent.size = ent.size_rounded = stats->size; + ent.count = stats->obj_count; return 0; } + int SFSBucket::check_bucket_shards(const DoutPrefixProvider* dpp) { ldpp_dout(dpp, 10) << __func__ << ": TODO" << dendl; return -ENOTSUP; diff --git a/src/rgw/driver/sfs/sqlite/sqlite_buckets.cc b/src/rgw/driver/sfs/sqlite/sqlite_buckets.cc index a3a509e2a64d7b..da1fc50584ab42 100644 --- a/src/rgw/driver/sfs/sqlite/sqlite_buckets.cc +++ b/src/rgw/driver/sfs/sqlite/sqlite_buckets.cc @@ -185,4 +185,36 @@ std::optional SQLiteBuckets::delete_bucket_transact( return retry.run(); } +const std::optional SQLiteBuckets::get_stats( + const std::string& bucket_id +) const { + auto storage = conn->get_storage(); + std::optional stats; + + auto res = storage.select( + columns( + count(&DBVersionedObject::object_id), sum(&DBVersionedObject::size) + ), + inner_join( + on(is_equal(&DBObject::uuid, &DBVersionedObject::object_id)) + ), + where( + is_equal(&DBObject::bucket_id, bucket_id) and + is_equal(&DBVersionedObject::object_state, ObjectState::COMMITTED) + ) + ); + + if (res.size() > 0) { + ceph_assert(res.size() == 1); + stats = SQLiteBuckets::Stats(); + stats->obj_count = std::get<0>(res[0]); + // We get a unique_ptr for SUM(), likely because of the underlying type of 'size'. + // Therefore we need to check whether it's a nullptr or not. + auto size = std::get<1>(res[0]).get(); + stats->size = (size ? *size : 0); + } + + return stats; +} + } // namespace rgw::sal::sfs::sqlite diff --git a/src/rgw/driver/sfs/sqlite/sqlite_buckets.h b/src/rgw/driver/sfs/sqlite/sqlite_buckets.h index a39170f461178e..20cac98dee90ca 100644 --- a/src/rgw/driver/sfs/sqlite/sqlite_buckets.h +++ b/src/rgw/driver/sfs/sqlite/sqlite_buckets.h @@ -28,6 +28,11 @@ class SQLiteBuckets { SQLiteBuckets(const SQLiteBuckets&) = delete; SQLiteBuckets& operator=(const SQLiteBuckets&) = delete; + struct Stats { + size_t size; + uint64_t obj_count; + }; + std::optional get_bucket(const std::string& bucket_id) const; std::vector get_bucket_by_name(const std::string& bucket_name ) const; @@ -52,6 +57,9 @@ class SQLiteBuckets { std::optional delete_bucket_transact( const std::string& bucket_id, uint max_objects, bool& bucket_deleted ) const; + const std::optional get_stats( + const std::string& bucket_id + ) const; }; } // namespace rgw::sal::sfs::sqlite