]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
include/encoding: parameterize stl containers encoders with allocator
authorSage Weil <sage@redhat.com>
Tue, 18 Oct 2016 02:42:17 +0000 (22:42 -0400)
committerSage Weil <sage@redhat.com>
Wed, 2 Nov 2016 17:48:49 +0000 (13:48 -0400)
This will let us encode/decode containers with custom allocators
(i.e., in mempools).

Signed-off-by: Sage Weil <sage@redhat.com>
src/include/encoding.h

index 2611330961dbd3f0a0df6fc59316762710ec3032..b8907897d29620b92d4b510df8eb1bc13ea453c2 100644 (file)
@@ -383,18 +383,18 @@ inline typename std::enable_if<!a_traits::supported ||
 }
 
 // std::list<T>
-template<class T, typename traits=denc_traits<T>>
+template<class T, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
-  encode(const std::list<T>& ls, bufferlist& bl)
+  encode(const std::list<T, Alloc>& ls, bufferlist& bl)
 {
   __u32 n = (__u32)(ls.size());  // c++11 std::list::size() is O(1)
   encode(n, bl);
   for (typename std::list<T>::const_iterator p = ls.begin(); p != ls.end(); ++p)
     encode(*p, bl);
 }
-template<class T, typename traits=denc_traits<T>>
+template<class T, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
-  encode(const std::list<T>& ls, bufferlist& bl, uint64_t features)
+  encode(const std::list<T,Alloc>& ls, bufferlist& bl, uint64_t features)
 {
   // should i pre- or post- count?
   if (!ls.empty()) {
@@ -415,9 +415,9 @@ inline typename std::enable_if<!traits::supported>::type
       encode(*p, bl, features);
   }
 }
-template<class T, typename traits=denc_traits<T>>
+template<class T, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
-  decode(std::list<T>& ls, bufferlist::iterator& p)
+  decode(std::list<T,Alloc>& ls, bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);
@@ -430,24 +430,27 @@ inline typename std::enable_if<!traits::supported>::type
 }
 
 // std::list<ceph::shared_ptr<T>>
-template<class T>
-inline void encode(const std::list<ceph::shared_ptr<T> >& ls, bufferlist& bl)
+template<class T, class Alloc>
+inline void encode(const std::list<ceph::shared_ptr<T>, Alloc>& ls,
+                  bufferlist& bl)
 {
   __u32 n = (__u32)(ls.size());  // c++11 std::list::size() is O(1)
   encode(n, bl);
   for (typename std::list<ceph::shared_ptr<T> >::const_iterator p = ls.begin(); p != ls.end(); ++p)
     encode(**p, bl);
 }
-template<class T>
-inline void encode(const std::list<ceph::shared_ptr<T> >& ls, bufferlist& bl, uint64_t features)
+template<class T, class Alloc>
+inline void encode(const std::list<ceph::shared_ptr<T>, Alloc>& ls,
+                  bufferlist& bl, uint64_t features)
 {
   __u32 n = (__u32)(ls.size());  // c++11 std::list::size() is O(1)
   encode(n, bl);
   for (typename std::list<ceph::shared_ptr<T> >::const_iterator p = ls.begin(); p != ls.end(); ++p)
     encode(**p, bl, features);
 }
-template<class T>
-inline void decode(std::list<ceph::shared_ptr<T> >& ls, bufferlist::iterator& p)
+template<class T, class Alloc>
+inline void decode(std::list<ceph::shared_ptr<T>, Alloc>& ls,
+                  bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);
@@ -460,41 +463,18 @@ inline void decode(std::list<ceph::shared_ptr<T> >& ls, bufferlist::iterator& p)
 }
 
 // std::set<T>
-template<class T, typename traits=denc_traits<T>>
+template<class T, class Comp, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
-  encode(const std::set<T>& s, bufferlist& bl)
+  encode(const std::set<T,Comp,Alloc>& s, bufferlist& bl)
 {
   __u32 n = (__u32)(s.size());
   encode(n, bl);
   for (typename std::set<T>::const_iterator p = s.begin(); p != s.end(); ++p)
     encode(*p, bl);
 }
-template<class T, typename traits=denc_traits<T>>
-inline typename std::enable_if<!traits::supported>::type
-  decode(std::set<T>& s, bufferlist::iterator& p)
-{
-  __u32 n;
-  decode(n, p);
-  s.clear();
-  while (n--) {
-    T v;
-    decode(v, p);
-    s.insert(v);
-  }
-}
-
-template<class T, class C, typename traits=denc_traits<T>>
-inline typename std::enable_if<!traits::supported>::type
-  encode(const std::set<T, C>& s, bufferlist& bl)
-{
-  __u32 n = (__u32)(s.size());
-  encode(n, bl);
-  for (typename std::set<T, C>::const_iterator p = s.begin(); p != s.end(); ++p)
-    encode(*p, bl);
-}
-template<class T, class C, typename traits=denc_traits<T>>
+template<class T, class Comp, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
-  decode(std::set<T, C>& s, bufferlist::iterator& p)
+  decode(std::set<T,Comp,Alloc>& s, bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);
@@ -506,16 +486,16 @@ inline typename std::enable_if<!traits::supported>::type
   }
 }
 
-template<class T, class C, typename traits=denc_traits<T>>
+template<class T, class Comp, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
encode_nohead(const std::set<T>& s, bufferlist& bl)
 encode_nohead(const std::set<T,Comp,Alloc>& s, bufferlist& bl)
 {
-  for (typename std::set<T>::const_iterator p = s.begin(); p != s.end(); ++p)
+  for (typename std::set<T,Comp>::const_iterator p = s.begin(); p != s.end(); ++p)
     encode(*p, bl);
 }
-template<class T, class C, typename traits=denc_traits<T>>
+template<class T, class Comp, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
decode_nohead(int len, std::set<T>& s, bufferlist::iterator& p)
 decode_nohead(int len, std::set<T,Comp,Alloc>& s, bufferlist::iterator& p)
 {
   for (int i=0; i<len; i++) {
     T v;
@@ -525,16 +505,16 @@ inline typename std::enable_if<!traits::supported>::type
 }
 
 // multiset
-template<class T>
-inline void encode(const std::multiset<T>& s, bufferlist& bl)
+template<class T, class Comp, class Alloc>
+inline void encode(const std::multiset<T,Comp,Alloc>& s, bufferlist& bl)
 {
   __u32 n = (__u32)(s.size());
   encode(n, bl);
-  for (typename std::multiset<T>::const_iterator p = s.begin(); p != s.end(); ++p)
+  for (typename std::multiset<T,Comp>::const_iterator p = s.begin(); p != s.end(); ++p)
     encode(*p, bl);
 }
-template<class T>
-inline void decode(std::multiset<T>& s, bufferlist::iterator& p)
+template<class T, class Comp, class Alloc>
+inline void decode(std::multiset<T,Comp,Alloc>& s, bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);
@@ -566,27 +546,27 @@ inline void decode(std::vector<T*>& v, bufferlist::iterator& p)
 }
 */
 // std::vector<T>
-template<class T, typename traits=denc_traits<T>>
+template<class T, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
encode(const std::vector<T>& v, bufferlist& bl, uint64_t features)
 encode(const std::vector<T,Alloc>& v, bufferlist& bl, uint64_t features)
 {
   __u32 n = (__u32)(v.size());
   encode(n, bl);
   for (typename std::vector<T>::const_iterator p = v.begin(); p != v.end(); ++p)
     encode(*p, bl, features);
 }
-template<class T, typename traits=denc_traits<T>>
+template<class T, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
encode(const std::vector<T>& v, bufferlist& bl)
 encode(const std::vector<T,Alloc>& v, bufferlist& bl)
 {
   __u32 n = (__u32)(v.size());
   encode(n, bl);
   for (typename std::vector<T>::const_iterator p = v.begin(); p != v.end(); ++p)
     encode(*p, bl);
 }
-template<class T, typename traits=denc_traits<T>>
+template<class T, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
decode(std::vector<T>& v, bufferlist::iterator& p)
 decode(std::vector<T,Alloc>& v, bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);
@@ -595,16 +575,16 @@ inline typename std::enable_if<!traits::supported>::type
     decode(v[i], p);
 }
 
-template<class T, typename traits=denc_traits<T>>
+template<class T, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
encode_nohead(const std::vector<T>& v, bufferlist& bl)
 encode_nohead(const std::vector<T,Alloc>& v, bufferlist& bl)
 {
   for (typename std::vector<T>::const_iterator p = v.begin(); p != v.end(); ++p)
     encode(*p, bl);
 }
-template<class T, typename traits=denc_traits<T>>
+template<class T, class Alloc, typename traits=denc_traits<T>>
 inline typename std::enable_if<!traits::supported>::type
decode_nohead(int len, std::vector<T>& v, bufferlist::iterator& p)
 decode_nohead(int len, std::vector<T,Alloc>& v, bufferlist::iterator& p)
 {
   v.resize(len);
   for (__u32 i=0; i<v.size(); i++) 
@@ -612,8 +592,9 @@ inline typename std::enable_if<!traits::supported>::type
 }
 
 // vector (shared_ptr)
-template<class T>
-inline void encode(const std::vector<ceph::shared_ptr<T> >& v, bufferlist& bl,
+template<class T,class Alloc>
+inline void encode(const std::vector<ceph::shared_ptr<T>,Alloc>& v,
+                  bufferlist& bl,
                   uint64_t features)
 {
   __u32 n = (__u32)(v.size());
@@ -624,8 +605,9 @@ inline void encode(const std::vector<ceph::shared_ptr<T> >& v, bufferlist& bl,
     else
       encode(T(), bl, features);
 }
-template<class T>
-inline void encode(const std::vector<ceph::shared_ptr<T> >& v, bufferlist& bl)
+template<class T, class Alloc>
+inline void encode(const std::vector<ceph::shared_ptr<T>,Alloc>& v,
+                  bufferlist& bl)
 {
   __u32 n = (__u32)(v.size());
   encode(n, bl);
@@ -635,8 +617,9 @@ inline void encode(const std::vector<ceph::shared_ptr<T> >& v, bufferlist& bl)
     else
       encode(T(), bl);
 }
-template<class T>
-inline void decode(std::vector<ceph::shared_ptr<T> >& v, bufferlist::iterator& p)
+template<class T, class Alloc>
+inline void decode(std::vector<ceph::shared_ptr<T>,Alloc>& v,
+                  bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);
@@ -673,59 +656,37 @@ inline void decode(std::map<T,U*>& m, bufferlist::iterator& p)
   }*/
 
 // map
-template<class T, class U,
+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 std::map<T,U>& m, bufferlist& bl)
-{
-  __u32 n = (__u32)(m.size());
-  encode(n, bl);
-  for (typename std::map<T,U>::const_iterator p = m.begin(); p != m.end(); ++p) {
-    encode(p->first, bl);
-    encode(p->second, bl);
-  }
-}
-template<class T, class U, class C>
-inline void encode(const std::map<T,U,C>& m, bufferlist& bl)
+  encode(const std::map<T,U,Comp,Alloc>& m, bufferlist& bl)
 {
   __u32 n = (__u32)(m.size());
   encode(n, bl);
-  for (typename std::map<T,U,C>::const_iterator p = m.begin(); p != m.end(); ++p) {
+  for (typename std::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,
+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 std::map<T,U>& m, bufferlist& bl, uint64_t features)
 encode(const std::map<T,U,Comp,Alloc>& m, bufferlist& bl, uint64_t features)
 {
   __u32 n = (__u32)(m.size());
   encode(n, bl);
-  for (typename std::map<T,U>::const_iterator p = m.begin(); p != m.end(); ++p) {
+  for (typename std::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,
+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(std::map<T,U>& 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 C>
-inline void decode(std::map<T,U,C>& m, bufferlist::iterator& p)
+  decode(std::map<T,U,Comp,Alloc>& m, bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);
@@ -736,19 +697,8 @@ inline void decode(std::map<T,U,C>& m, bufferlist::iterator& p)
     decode(m[k], p);
   }
 }
-template<class T, class U, class C>
-inline void decode_noclear(std::map<T,U,C>& 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>
-inline void decode_noclear(std::map<T,U>& m, bufferlist::iterator& p)
+template<class T, class U, class Comp, class Alloc>
+inline void decode_noclear(std::map<T,U,Comp,Alloc>& m, bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);
@@ -758,33 +708,33 @@ inline void decode_noclear(std::map<T,U>& m, bufferlist::iterator& p)
     decode(m[k], p);
   }
 }
-template<class T, class U,
+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 std::map<T,U>& m, bufferlist& bl)
 encode_nohead(const std::map<T,U,Comp,Alloc>& m, bufferlist& bl)
 {
-  for (typename std::map<T,U>::const_iterator p = m.begin(); p != m.end(); ++p) {
+  for (typename std::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,
+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 std::map<T,U>& m, bufferlist& bl, uint64_t features)
 encode_nohead(const std::map<T,U,Comp,Alloc>& m, bufferlist& bl, uint64_t features)
 {
-  for (typename std::map<T,U>::const_iterator p = m.begin(); p != m.end(); ++p) {
+  for (typename std::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,
+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, std::map<T,U>& m, bufferlist::iterator& p)
 decode_nohead(int n, std::map<T,U,Comp,Alloc>& m, bufferlist::iterator& p)
 {
   m.clear();
   while (n--) {
@@ -795,18 +745,18 @@ inline typename std::enable_if<!t_traits::supported ||
 }
 
 // multimap
-template<class T, class U>
-inline void encode(const std::multimap<T,U>& m, bufferlist& bl)
+template<class T, class U, class Comp, class Alloc>
+inline void encode(const std::multimap<T,U,Comp,Alloc>& m, bufferlist& bl)
 {
   __u32 n = (__u32)(m.size());
   encode(n, bl);
-  for (typename std::multimap<T,U>::const_iterator p = m.begin(); p != m.end(); ++p) {
+  for (typename std::multimap<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>
-inline void decode(std::multimap<T,U>& m, bufferlist::iterator& p)
+template<class T, class U, class Comp, class Alloc>
+inline void decode(std::multimap<T,U,Comp,Alloc>& m, bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);
@@ -814,35 +764,35 @@ inline void decode(std::multimap<T,U>& m, bufferlist::iterator& p)
   while (n--) {
     typename std::pair<T,U> tu = std::pair<T,U>();
     decode(tu.first, p);
-    typename std::multimap<T,U>::iterator it = m.insert(tu);
+    typename std::multimap<T,U,Comp,Alloc>::iterator it = m.insert(tu);
     decode(it->second, p);
   }
 }
 
 // ceph::unordered_map
-template<class T, class U>
-inline void encode(const unordered_map<T,U>& m, bufferlist& bl,
+template<class T, class U, class Hash, class Pred, class Alloc>
+inline void encode(const unordered_map<T,U,Hash,Pred,Alloc>& m, bufferlist& bl,
                   uint64_t features)
 {
   __u32 n = (__u32)(m.size());
   encode(n, bl);
-  for (typename unordered_map<T,U>::const_iterator p = m.begin(); p != m.end(); ++p) {
+  for (typename unordered_map<T,U,Hash,Pred>::const_iterator p = m.begin(); p != m.end(); ++p) {
     encode(p->first, bl, features);
     encode(p->second, bl, features);
   }
 }
-template<class T, class U>
-inline void encode(const unordered_map<T,U>& m, bufferlist& bl)
+template<class T, class U, class Hash, class Pred, class Alloc>
+inline void encode(const unordered_map<T,U,Hash,Pred,Alloc>& m, bufferlist& bl)
 {
   __u32 n = (__u32)(m.size());
   encode(n, bl);
-  for (typename unordered_map<T,U>::const_iterator p = m.begin(); p != m.end(); ++p) {
+  for (typename unordered_map<T,U,Hash,Pred,Alloc>::const_iterator p = m.begin(); p != m.end(); ++p) {
     encode(p->first, bl);
     encode(p->second, bl);
   }
 }
-template<class T, class U>
-inline void decode(unordered_map<T,U>& m, bufferlist::iterator& p)
+template<class T, class U, class Hash, class Pred, class Alloc>
+inline void decode(unordered_map<T,U,Hash,Pred,Alloc>& m, bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);
@@ -855,16 +805,16 @@ inline void decode(unordered_map<T,U>& m, bufferlist::iterator& p)
 }
 
 // ceph::unordered_set
-template<class T>
-inline void encode(const ceph::unordered_set<T>& m, bufferlist& bl)
+template<class T, class Hash, class Pred, class Alloc>
+inline void encode(const ceph::unordered_set<T,Hash,Pred,Alloc>& m, bufferlist& bl)
 {
   __u32 n = (__u32)(m.size());
   encode(n, bl);
-  for (typename ceph::unordered_set<T>::const_iterator p = m.begin(); p != m.end(); ++p)
+  for (typename ceph::unordered_set<T,Hash,Pred>::const_iterator p = m.begin(); p != m.end(); ++p)
     encode(*p, bl);
 }
-template<class T>
-inline void decode(ceph::unordered_set<T>& m, bufferlist::iterator& p)
+template<class T, class Hash, class Pred, class Alloc>
+inline void decode(ceph::unordered_set<T,Hash,Pred,Alloc>& m, bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);
@@ -877,24 +827,24 @@ inline void decode(ceph::unordered_set<T>& m, bufferlist::iterator& p)
 }
 
 // deque
-template<class T>
-inline void encode(const std::deque<T>& ls, bufferlist& bl, uint64_t features)
+template<class T, class Alloc>
+inline void encode(const std::deque<T,Alloc>& ls, bufferlist& bl, uint64_t features)
 {
   __u32 n = ls.size();
   encode(n, bl);
   for (typename std::deque<T>::const_iterator p = ls.begin(); p != ls.end(); ++p)
     encode(*p, bl, features);
 }
-template<class T>
-inline void encode(const std::deque<T>& ls, bufferlist& bl)
+template<class T, class Alloc>
+inline void encode(const std::deque<T,Alloc>& ls, bufferlist& bl)
 {
   __u32 n = ls.size();
   encode(n, bl);
   for (typename std::deque<T>::const_iterator p = ls.begin(); p != ls.end(); ++p)
     encode(*p, bl);
 }
-template<class T>
-inline void decode(std::deque<T>& ls, bufferlist::iterator& p)
+template<class T, class Alloc>
+inline void decode(std::deque<T,Alloc>& ls, bufferlist::iterator& p)
 {
   __u32 n;
   decode(n, p);