diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-09-26 13:24:48 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-09-26 14:07:46 -0700 |
commit | db5bbdd014440a05798659a73c200c8bee3c2e51 (patch) | |
tree | 58034253e98a3f7e12377019b8f8cf2861a6c487 | |
parent | 9adb73ae41477659dcae1b7b2c4e15a00eb13ca7 (diff) | |
download | ceph-db5bbdd014440a05798659a73c200c8bee3c2e51.tar.gz |
rgw: quota utility class
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | src/rgw/Makefile.am | 2 | ||||
-rw-r--r-- | src/rgw/rgw_common.h | 9 | ||||
-rw-r--r-- | src/rgw/rgw_quota.cc | 76 | ||||
-rw-r--r-- | src/rgw/rgw_quota.h | 32 |
4 files changed, 119 insertions, 0 deletions
diff --git a/src/rgw/Makefile.am b/src/rgw/Makefile.am index 24060b52e25..27891efd124 100644 --- a/src/rgw/Makefile.am +++ b/src/rgw/Makefile.am @@ -50,6 +50,7 @@ LIBRGW_DEPS += \ -lfcgi radosgw_SOURCES = \ + rgw/rgw_quota.cc \ rgw/rgw_resolve.cc \ rgw/rgw_rest.cc \ rgw/rgw_rest_swift.cc \ @@ -124,6 +125,7 @@ noinst_HEADERS += \ rgw/rgw_http_client.h \ rgw/rgw_swift.h \ rgw/rgw_swift_auth.h \ + rgw/rgw_quota.h \ rgw/rgw_rados.h \ rgw/rgw_replica_log.h \ rgw/rgw_resolve.h \ diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 2c7c0c716be..e514a9b8079 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -599,6 +599,10 @@ struct rgw_bucket { void dump(Formatter *f) const; void decode_json(JSONObj *obj); static void generate_test_instances(list<rgw_bucket*>& o); + + bool operator<(const rgw_bucket& b) const { + return name.compare(b.name) < 0; + } }; WRITE_CLASS_ENCODER(rgw_bucket) @@ -1213,6 +1217,11 @@ static inline const char *rgw_obj_category_name(RGWObjCategory category) return "unknown"; } +static inline uint64_t rgw_rounded_kb(uint64_t bytes) +{ + return (bytes + 1023) / 1024; +} + extern string rgw_string_unquote(const string& s); extern void parse_csv_string(const string& ival, vector<string>& ovals); extern int parse_key_value(string& in_str, string& key, string& val); diff --git a/src/rgw/rgw_quota.cc b/src/rgw/rgw_quota.cc new file mode 100644 index 00000000000..c466b3ca416 --- /dev/null +++ b/src/rgw/rgw_quota.cc @@ -0,0 +1,76 @@ + +#include "include/utime.h" +#include "common/lru_map.h" + +#include "rgw_common.h" +#include "rgw_rados.h" +#include "rgw_quota.h" + +#define dout_subsys ceph_subsys_rgw + + +int RGWBucketStatsCache::fetch_bucket_totals(rgw_bucket& bucket, RGWBucketStats& stats) +{ + RGWBucketInfo bucket_info; + + uint64_t bucket_ver; + uint64_t master_ver; + + map<RGWObjCategory, RGWBucketStats> bucket_stats; + int r = store->get_bucket_stats(bucket, &bucket_ver, &master_ver, bucket_stats, NULL); + if (r < 0) { + ldout(store->ctx(), 0) << "could not get bucket info for bucket=" << bucket.name << dendl; + return r; + } + + map<RGWObjCategory, RGWBucketStats>::iterator iter; + for (iter = bucket_stats.begin(); iter != bucket_stats.end(); ++iter) { + RGWBucketStats& s = iter->second; + stats.num_kb += s.num_kb; + stats.num_kb_rounded += s.num_kb_rounded; + stats.num_objects += s.num_objects; + } + + return 0; +} + +int RGWBucketStatsCache::get_bucket_stats(rgw_bucket& bucket, RGWBucketStats& stats) { + RGWQuotaBucketStats qs; + if (stats_map.find(bucket, qs)) { + if (qs.expiration > ceph_clock_now(store->ctx())) { + stats = qs.stats; + return 0; + } + } + + int ret = fetch_bucket_totals(bucket, qs.stats); + if (ret < 0 && ret != -ENOENT) + return ret; + + qs.expiration = ceph_clock_now(store->ctx()) + store->ctx()->_conf->rgw_bucket_quota_ttl; + + stats_map.add(bucket, qs); + + return 0; +} + + +void RGWBucketStatsCache::adjust_bucket_stats(rgw_bucket& bucket, int objs_delta, uint64_t added_bytes, uint64_t removed_bytes) +{ + RGWQuotaBucketStats qs; + if (!stats_map.find(bucket, qs)) { + /* not have cached info, can't update anything */ + return; + } + + uint64_t rounded_kb_added = rgw_rounded_kb(added_bytes); + uint64_t rounded_kb_removed = rgw_rounded_kb(removed_bytes); + + qs.stats.num_kb_rounded += (rounded_kb_added - rounded_kb_removed); + qs.stats.num_kb += (added_bytes - removed_bytes) / 1024; + qs.stats.num_objects += objs_delta; + + stats_map.add(bucket, qs); +} + + diff --git a/src/rgw/rgw_quota.h b/src/rgw/rgw_quota.h new file mode 100644 index 00000000000..e37e0b473f5 --- /dev/null +++ b/src/rgw/rgw_quota.h @@ -0,0 +1,32 @@ +#ifndef CEPH_RGW_QUOTA_H +#define CEPH_RGW_QUOTA_H + + +#include "include/utime.h" +#include "common/lru_map.h" + +class RGWRados; + +struct RGWQuotaBucketStats { + RGWBucketStats stats; + utime_t expiration; +}; + + +class RGWBucketStatsCache { + RGWRados *store; + lru_map<rgw_bucket, RGWQuotaBucketStats> stats_map; + + int fetch_bucket_totals(rgw_bucket& bucket, RGWBucketStats& stats); + +public: +#warning FIXME configurable stats_map size + RGWBucketStatsCache(RGWRados *_store) : store(_store), stats_map(10000) {} + + int get_bucket_stats(rgw_bucket& bucket, RGWBucketStats& stats); +}; + + + + +#endif |