summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-09-26 13:24:48 -0700
committerYehuda Sadeh <yehuda@inktank.com>2013-09-26 14:07:46 -0700
commitdb5bbdd014440a05798659a73c200c8bee3c2e51 (patch)
tree58034253e98a3f7e12377019b8f8cf2861a6c487
parent9adb73ae41477659dcae1b7b2c4e15a00eb13ca7 (diff)
downloadceph-db5bbdd014440a05798659a73c200c8bee3c2e51.tar.gz
rgw: quota utility class
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/rgw/Makefile.am2
-rw-r--r--src/rgw/rgw_common.h9
-rw-r--r--src/rgw/rgw_quota.cc76
-rw-r--r--src/rgw/rgw_quota.h32
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