From: Matt Benjamin Date: Mon, 14 Nov 2016 22:38:57 +0000 (-0500) Subject: rgw: custom headers: use boost::container::flat_map X-Git-Tag: v11.1.1~63^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4092c97ee5aa2f187199076bf1afc3146567f2d9;p=ceph.git rgw: custom headers: use boost::container::flat_map Use this occasion of serialized map to implement encoders for boost::container::flat_map, which is optimized for in-order insertion. After some discussion, I'm proposing to just add the new template forms, rather than (e.g.) adding either a large amount of specialization machinery, or alternatively using C-style macros. Signed-off-by: Matt Benjamin --- diff --git a/src/include/denc.h b/src/include/denc.h index 4f310ea0b0cc..7e4564bc042e 100644 --- a/src/include/denc.h +++ b/src/include/denc.h @@ -31,6 +31,7 @@ #include #include #include +#include #include "include/int_types.h" #include "include/intarith.h" @@ -1061,6 +1062,134 @@ struct denc_traits< } }; +// boost::container::flat_map +template +struct denc_traits< + boost::container::flat_map, + typename std::enable_if::supported != 0 && + denc_traits::supported != 0>::type> { + typedef denc_traits a_traits; + typedef denc_traits b_traits; + + enum { supported = true }; + enum { featured = a_traits::featured || b_traits::featured }; + enum { bounded = a_traits::bounded && b_traits::bounded }; + + template + static typename std::enable_if::type + bound_encode(const boost::container::flat_map& v, size_t& p) { + denc((uint32_t)v.size(), p); + for (const auto& i : v) { + denc(i.first, p); + denc(i.second, p); + } + } + template + static typename std::enable_if::type + bound_encode(const boost::container::flat_map& v, size_t& p, + uint64_t f) { + denc((uint32_t)v.size(), p); + for (const auto& i : v) { + denc(i.first, p, f); + denc(i.second, p, f); + } + } + template + static typename std::enable_if::type + bound_encode(const boost::container::flat_map& v, size_t& p) { + denc((uint32_t)v.size(), p); + size_t elem_size = 0; + denc(*(A*)nullptr, elem_size); + denc(*(B*)nullptr, elem_size); + p += v.size() * elem_size; + } + template + static typename std::enable_if::type + bound_encode(const boost::container::flat_map& v, size_t& p, + uint64_t f) { + denc((uint32_t)v.size(), p); + size_t elem_size = 0; + denc(*(A*)nullptr, elem_size, f); + denc(*(B*)nullptr, elem_size, f); + p += v.size() * elem_size; + } + + template + static typename std::enable_if::type + encode(const boost::container::flat_map& v, + bufferlist::contiguous_appender& p) { + denc((uint32_t)v.size(), p); + for (const auto& i : v) { + denc(i.first, p); + denc(i.second, p); + } + } + template + static typename std::enable_if::type + encode(const boost::container::flat_map& v, + bufferlist::contiguous_appender& p, + uint64_t f) { + denc((uint32_t)v.size(), p); + for (const auto& i : v) { + denc(i.first, p, f); + denc(i.second, p, f); + } + } + + static void decode(boost::container::flat_map& v, + buffer::ptr::iterator& p) { + v.clear(); + uint32_t num; + denc(num, p); + A key; + while (num--) { + denc(key, p); + denc(v[key], p); + } + } + + // nohead variants + template + static typename std::enable_if::type + encode_nohead(const boost::container::flat_map& v, + bufferlist::contiguous_appender& p) { + for (const auto& i : v) { + denc(i.first, p); + denc(i.second, p); + } + } + template + static typename std::enable_if::type + encode_nohead(const boost::container::flat_map& v, + bufferlist::contiguous_appender& p, + uint64_t f) { + for (const auto& i : v) { + denc(i.first, p, f); + denc(i.second, p, f); + } + } + static void decode_nohead(size_t num, boost::container::flat_map& v, + buffer::ptr::iterator& p) { + v.clear(); + A key; + while (num--) { + denc(key, p); + denc(v[key], p); + } + } +}; // ---------------------------------------------------------------------- // class helpers diff --git a/src/include/encoding.h b/src/include/encoding.h index b21fd6e37a3f..cbc762351d7b 100644 --- a/src/include/encoding.h +++ b/src/include/encoding.h @@ -744,6 +744,104 @@ inline typename std::enable_if, typename u_traits=denc_traits> + inline typename std::enable_if::type + encode(const boost::container::flat_map& m, bufferlist& bl) +{ + __u32 n = (__u32)(m.size()); + encode(n, bl); + for (typename boost::container::flat_map::const_iterator p + = m.begin(); p != m.end(); ++p) { + encode(p->first, bl); + encode(p->second, bl); + } +} +template, typename u_traits=denc_traits> + inline typename std::enable_if::type + encode(const boost::container::flat_map& m, bufferlist& bl, + uint64_t features) +{ + __u32 n = (__u32)(m.size()); + encode(n, bl); + for (typename boost::container::flat_map::const_iterator p + = m.begin(); p != m.end(); ++p) { + encode(p->first, bl, features); + encode(p->second, bl, features); + } +} +template, typename u_traits=denc_traits> + inline typename std::enable_if::type + decode(boost::container::flat_map& m, bufferlist::iterator& p) +{ + __u32 n; + decode(n, p); + m.clear(); + while (n--) { + T k; + decode(k, p); + decode(m[k], p); + } +} +template +inline void decode_noclear(boost::container::flat_map& m, + bufferlist::iterator& p) +{ + __u32 n; + decode(n, p); + while (n--) { + T k; + decode(k, p); + decode(m[k], p); + } +} +template, typename u_traits=denc_traits> + inline typename std::enable_if::type + encode_nohead(const boost::container::flat_map& m, + bufferlist& bl) +{ + for (typename boost::container::flat_map::const_iterator p + = m.begin(); p != m.end(); ++p) { + encode(p->first, bl); + encode(p->second, bl); + } +} +template, typename u_traits=denc_traits> + inline typename std::enable_if::type + encode_nohead(const boost::container::flat_map& m, + bufferlist& bl, uint64_t features) +{ + for (typename boost::container::flat_map::const_iterator p + = m.begin(); p != m.end(); ++p) { + encode(p->first, bl, features); + encode(p->second, bl, features); + } +} +template, typename u_traits=denc_traits> +inline typename std::enable_if::type + decode_nohead(int n, boost::container::flat_map& m, + bufferlist::iterator& p) +{ + m.clear(); + while (n--) { + T k; + decode(k, p); + decode(m[k], p); + } +} + // multimap template inline void encode(const std::multimap& m, bufferlist& bl) diff --git a/src/rgw/rgw_log.h b/src/rgw/rgw_log.h index ab800c7fa2ab..4a81fefd8406 100644 --- a/src/rgw/rgw_log.h +++ b/src/rgw/rgw_log.h @@ -4,7 +4,7 @@ #ifndef CEPH_RGW_LOG_H #define CEPH_RGW_LOG_H -#include +#include #include "rgw_common.h" #include "include/utime.h" #include "common/Formatter.h" @@ -14,7 +14,7 @@ class RGWRados; struct rgw_log_entry { - using headers_map = std::map; + using headers_map = boost::container::flat_map; rgw_user object_owner; rgw_user bucket_owner;