]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: custom headers: use boost::container::flat_map
authorMatt Benjamin <mbenjamin@redhat.com>
Mon, 14 Nov 2016 22:38:57 +0000 (17:38 -0500)
committerMatt Benjamin <mbenjamin@redhat.com>
Tue, 13 Dec 2016 23:14:13 +0000 (18:14 -0500)
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 <mbenjamin@redhat.com>
src/include/denc.h
src/include/encoding.h
src/rgw/rgw_log.h

index 4f310ea0b0cc19c405af7d51c6458e112766ce0b..7e4564bc042edabe7a54e831e7a7a072a0e1329b 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <type_traits>
 #include <boost/intrusive/set.hpp>
+#include <boost/container/flat_map.hpp>
 
 #include "include/int_types.h"
 #include "include/intarith.h"
@@ -1061,6 +1062,134 @@ struct denc_traits<
   }
 };
 
+// boost::container::flat_map
+template<typename A, typename B>
+struct denc_traits<
+  boost::container::flat_map<A, B>,
+  typename std::enable_if<denc_traits<A>::supported != 0 &&
+                         denc_traits<B>::supported != 0>::type> {
+  typedef denc_traits<A> a_traits;
+  typedef denc_traits<B> b_traits;
+
+  enum { supported = true };
+  enum { featured = a_traits::featured || b_traits::featured };
+  enum { bounded = a_traits::bounded && b_traits::bounded };
+
+  template<typename AA=A>
+  static typename std::enable_if<sizeof(AA) &&
+                                !bounded &&
+                                !featured>::type
+  bound_encode(const boost::container::flat_map<A,B>& v, size_t& p) {
+    denc((uint32_t)v.size(), p);
+    for (const auto& i : v) {
+      denc(i.first, p);
+      denc(i.second, p);
+    }
+  }
+  template<typename AA=A>
+  static typename std::enable_if<sizeof(AA) &&
+                                !bounded &&
+                                featured, void>::type
+  bound_encode(const boost::container::flat_map<A,B>& 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<typename AA=A>
+  static typename std::enable_if<sizeof(AA) &&
+                                bounded &&
+                                !featured>::type
+  bound_encode(const boost::container::flat_map<A,B>& 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<typename AA=A>
+  static typename std::enable_if<sizeof(AA) &&
+                                bounded &&
+                                featured, void>::type
+  bound_encode(const boost::container::flat_map<A,B>& 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<typename AA=A>
+  static typename std::enable_if<sizeof(AA) &&
+                                !featured>::type
+  encode(const boost::container::flat_map<A,B>& 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<typename AA=A>
+  static typename std::enable_if<sizeof(AA) &&
+                                featured, void>::type
+  encode(const boost::container::flat_map<A,B>& 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<A,B>& 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<typename AA=A>
+  static typename std::enable_if<sizeof(AA) &&
+                                !featured>::type
+  encode_nohead(const boost::container::flat_map<A,B>& v,
+               bufferlist::contiguous_appender& p) {
+    for (const auto& i : v) {
+      denc(i.first, p);
+      denc(i.second, p);
+    }
+  }
+  template<typename AA=A>
+  static typename std::enable_if<sizeof(AA) &&
+                                featured, void>::type
+  encode_nohead(const boost::container::flat_map<A,B>& 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<A,B>& v,
+                           buffer::ptr::iterator& p) {
+    v.clear();
+    A key;
+    while (num--) {
+      denc(key, p);
+      denc(v[key], p);
+    }
+  }
+};
 
 // ----------------------------------------------------------------------
 // class helpers
index b21fd6e37a3feb5f5284bb99c0b503c21d80aff4..cbc762351d7b9d8fe91cbbee7dbfd95e0a3692ef 100644 (file)
@@ -744,6 +744,104 @@ inline typename std::enable_if<!t_traits::supported ||
   }
 }
 
+// boost::container::flat-map
+template<class T, class U, class Comp, class Alloc,
+        typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+  inline typename std::enable_if<!t_traits::supported ||
+                                !u_traits::supported>::type
+  encode(const boost::container::flat_map<T,U,Comp,Alloc>& m, bufferlist& bl)
+{
+  __u32 n = (__u32)(m.size());
+  encode(n, bl);
+  for (typename boost::container::flat_map<T,U,Comp>::const_iterator p
+        = m.begin(); p != m.end(); ++p) {
+    encode(p->first, bl);
+    encode(p->second, bl);
+  }
+}
+template<class T, class U, class Comp, class Alloc,
+        typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+  inline typename std::enable_if<!t_traits::supported ||
+                                !u_traits::supported>::type
+  encode(const boost::container::flat_map<T,U,Comp,Alloc>& m, bufferlist& bl,
+        uint64_t features)
+{
+  __u32 n = (__u32)(m.size());
+  encode(n, bl);
+  for (typename boost::container::flat_map<T,U,Comp>::const_iterator p
+        = m.begin(); p != m.end(); ++p) {
+    encode(p->first, bl, features);
+    encode(p->second, bl, features);
+  }
+}
+template<class T, class U, class Comp, class Alloc,
+        typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+  inline typename std::enable_if<!t_traits::supported ||
+                                !u_traits::supported>::type
+  decode(boost::container::flat_map<T,U,Comp,Alloc>& m, bufferlist::iterator& p)
+{
+  __u32 n;
+  decode(n, p);
+  m.clear();
+  while (n--) {
+    T k;
+    decode(k, p);
+    decode(m[k], p);
+  }
+}
+template<class T, class U, class Comp, class Alloc>
+inline void decode_noclear(boost::container::flat_map<T,U,Comp,Alloc>& m,
+                          bufferlist::iterator& p)
+{
+  __u32 n;
+  decode(n, p);
+  while (n--) {
+    T k;
+    decode(k, p);
+    decode(m[k], p);
+  }
+}
+template<class T, class U, class Comp, class Alloc,
+        typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+  inline typename std::enable_if<!t_traits::supported ||
+                                !u_traits::supported>::type
+  encode_nohead(const boost::container::flat_map<T,U,Comp,Alloc>& m,
+               bufferlist& bl)
+{
+  for (typename boost::container::flat_map<T,U,Comp>::const_iterator p
+        = m.begin(); p != m.end(); ++p) {
+    encode(p->first, bl);
+    encode(p->second, bl);
+  }
+}
+template<class T, class U, class Comp, class Alloc,
+        typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+  inline typename std::enable_if<!t_traits::supported ||
+                                !u_traits::supported>::type
+  encode_nohead(const boost::container::flat_map<T,U,Comp,Alloc>& m,
+               bufferlist& bl, uint64_t features)
+{
+  for (typename boost::container::flat_map<T,U,Comp>::const_iterator p
+        = m.begin(); p != m.end(); ++p) {
+    encode(p->first, bl, features);
+    encode(p->second, bl, features);
+  }
+}
+template<class T, class U, class Comp, class Alloc,
+        typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+inline typename std::enable_if<!t_traits::supported ||
+                                !u_traits::supported>::type
+  decode_nohead(int n, boost::container::flat_map<T,U,Comp,Alloc>& m,
+               bufferlist::iterator& p)
+{
+  m.clear();
+  while (n--) {
+    T k;
+    decode(k, p);
+    decode(m[k], p);
+  }
+}
+
 // multimap
 template<class T, class U, class Comp, class Alloc>
 inline void encode(const std::multimap<T,U,Comp,Alloc>& m, bufferlist& bl)
index ab800c7fa2ab1d815eaefed31633cad76d4f79b4..4a81fefd8406ec8747578e3d14a2aefcfc3a6a35 100644 (file)
@@ -4,7 +4,7 @@
 #ifndef CEPH_RGW_LOG_H
 #define CEPH_RGW_LOG_H
 
-#include <boost/container/flat_set.hpp>
+#include <boost/container/flat_map.hpp>
 #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<std::string, std::string>;
+  using headers_map = boost::container::flat_map<std::string, std::string>;
 
   rgw_user object_owner;
   rgw_user bucket_owner;