]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
* buffer.h encoder/decoder rewrite; can now encode/dequeue any stl-based structure...
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Wed, 28 Mar 2007 22:50:51 +0000 (22:50 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Wed, 28 Mar 2007 22:50:51 +0000 (22:50 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1316 29311d96-e01e-0410-9327-a35deaab8ce9

branches/sage/cephmds2/include/buffer.h

index 640aad7766434ced156ae35d656f3df395ac5ed1..0252b3938d0fd94e99733a95b2fd9a393f471e2e 100644 (file)
@@ -745,472 +745,226 @@ inline std::ostream& operator<<(std::ostream& out, const buffer::list& bl) {
 
 
 
-// encoder/decode helpers
+// ----------------------------------------------------------
+// new encoders
 
-// -- basic types --
-// string
-inline void _encode(const std::string& s, bufferlist& bl) 
-{
-  bl.append(s.c_str(), s.length()+1);
-}
-inline void _decode(std::string& s, bufferlist& bl, int& off)
-{
-  s = bl.c_str() + off;
-  off += s.length() + 1;
-}
-
-// bufferptr (encapsulated)
-inline void _encode(bufferptr& bp, bufferlist& bl) 
-{
-  size_t len = bp.length();
-  bl.append((char*)&len, sizeof(len));
-  bl.append(bp);
-}
-inline void _decode(bufferptr& bp, bufferlist& bl, int& off)
-{
-  size_t len;
-  bl.copy(off, sizeof(len), (char*)&len);
-  off += sizeof(len);
-  bufferlist s;
-  s.substr_of(bl, off, len);
-  off += len;
-
-  if (s.buffers().size() == 1)
-    bp = s.buffers().front();
-  else
-    bp = buffer::copy(s.c_str(), s.length());
-}
-
-// bufferlist (encapsulated)
-inline void _encode(const bufferlist& s, bufferlist& bl) 
+// raw
+template<class T>
+inline void _encoderaw(const T& t, bufferlist& bl)
 {
-  size_t len = s.length();
-  bl.append((char*)&len, sizeof(len));
-  bl.append(s);
+  bl.append((char*)&t, sizeof(t));
 }
-inline void _decode(bufferlist& s, bufferlist& bl, int& off)
+template<class T>
+inline void _decoderaw(T& t, bufferlist& bl, int& off)
 {
-  size_t len;
-  bl.copy(off, sizeof(len), (char*)&len);
-  off += sizeof(len);
-  s.substr_of(bl, off, len);
-  off += len;
+  bl.copy(off, sizeof(t), (char*)&t);
+  off += sizeof(t);
 }
 
-
 #include <set>
 #include <map>
+#include <deque>
 #include <vector>
 #include <string>
 #include <ext/hash_map>
 
-// set<string>
-inline void _encode(const std::set<std::string>& s, bufferlist& bl)
-{
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (std::set<std::string>::const_iterator it = s.begin();
-       it != s.end();
-       it++) {
-    ::_encode(*it, bl);
-    n--;
-  }
-  assert(n==0);
-}
-inline void _decode(std::set<std::string>& s, bufferlist& bl, int& off) 
-{
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  for (int i=0; i<n; i++) {
-    std::string v;
-    ::_decode(v, bl, off);
-    s.insert(v);
-  }
-  assert(s.size() == (unsigned)n);
-}
-// vector<string>
-inline void _encode(std::vector<std::string>& s, bufferlist& bl)
-{
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (std::vector<std::string>::const_iterator it = s.begin();
-       it != s.end();
-       it++) {
-    ::_encode(*it, bl);
-    n--;
-  }
-  assert(n==0);
-}
-inline void _decode(std::vector<std::string>& s, bufferlist& bl, int& off) 
-{
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  s = std::vector<std::string>(n);
-  for (int i=0; i<n; i++) {
-    ::_decode(s[i], bl, off);
-  }
-  assert(s.size() == (unsigned)n);
-}
-
-// list<bufferlist>
-inline void _encode(const std::list<bufferlist>& s, bufferlist& bl)
+// list
+template<class T>
+inline void _encode(const std::list<T>& ls, bufferlist& bl)
 {
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (std::list<bufferlist>::const_iterator it = s.begin();
-       it != s.end();
-       it++) {
-    ::_encode(*it, bl);
-    n--;
-  }
-  assert(n==0);
+  __uint32_t n = ls.size();
+  _encoderaw(n, bl);
+  for (typename std::list<T>::const_iterator p = ls.begin(); p != ls.end(); ++p)
+    _encode(*p, bl);
 }
-inline void _decode(std::list<bufferlist>& s, bufferlist& bl, int& off) 
+template<class T>
+inline void _decode(std::list<T>& ls, bufferlist& bl, int& off)
 {
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  for (int i=0; i<n; i++) {
-    bufferlist v;
-    s.push_back(v);
-    ::_decode(s.back(), bl, off);
+  __uint32_t n;
+  _decoderaw(n, bl, off);
+  ls.clear();
+  while (n--) {
+    T v;
+    _decode(v, bl, off);
+    ls.push_back(v);
   }
-  //assert(s.size() == (unsigned)n);
 }
 
-
-// set<T>
+// deque
 template<class T>
-inline void _encode(const std::set<T>& s, bufferlist& bl)
+inline void _encode(const std::deque<T>& ls, bufferlist& bl)
 {
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (typename std::set<T>::const_iterator it = s.begin();
-       it != s.end();
-       it++) {
-    T v = *it;
-    bl.append((char*)&v, sizeof(v));
-    n--;
-  }
-  assert(n==0);
+  __uint32_t n = ls.size();
+  _encoderaw(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::set<T>& s, bufferlist& bl, int& off) 
+inline void _decode(std::deque<T>& ls, bufferlist& bl, int& off)
 {
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  for (int i=0; i<n; i++) {
+  __uint32_t n;
+  _decoderaw(n, bl, off);
+  ls.clear();
+  while (n--) {
     T v;
-    bl.copy(off, sizeof(v), (char*)&v);
-    off += sizeof(v);
-    s.insert(v);
+    _decode(v, bl, off);
+    ls.push_back(v);
   }
-  assert(s.size() == (unsigned)n);
 }
 
-// vector<T>
+// set
 template<class T>
-inline void _encode(std::vector<T>& s, bufferlist& bl)
+inline void _encode(const std::set<T>& s, bufferlist& bl)
 {
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (typename std::vector<T>::iterator it = s.begin();
-       it != s.end();
-       it++) {
-    T v = *it;
-    bl.append((char*)&v, sizeof(v));
-    n--;
-  }
-  assert(n==0);
+  __uint32_t n = s.size();
+  _encoderaw(n, bl);
+  for (typename std::set<T>::const_iterator p = s.begin(); p != s.end(); ++p)
+    _encode(*p, bl);
 }
 template<class T>
-inline void _decode(std::vector<T>& s, bufferlist& bl, int& off) 
+inline void _decode(std::set<T>& s, bufferlist& bl, int& off)
 {
+  __uint32_t n;
+  _decoderaw(n, bl, off);
   s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  s = std::vector<T>(n);
-  for (int i=0; i<n; i++) {
+  while (n--) {
     T v;
-    bl.copy(off, sizeof(v), (char*)&v);
-    off += sizeof(v);
-    s[i] = v;
+    _decode(v, bl, off);
+    s.insert(v);
   }
-  assert(s.size() == (unsigned)n);
 }
 
-// list<T>
+// vector
 template<class T>
-inline void _encode(const std::list<T>& s, bufferlist& bl)
+inline void _encode(const std::vector<T>& v, bufferlist& bl)
 {
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (typename std::list<T>::const_iterator it = s.begin();
-       it != s.end();
-       it++) {
-    T v = *it;
-    bl.append((char*)&v, sizeof(v));
-    n--;
-  }
-  assert(n==0);
+  __uint32_t n = v.size();
+  _encoderaw(n, bl);
+  for (typename std::vector<T>::const_iterator p = v.begin(); p != v.end(); ++p)
+    _encode(*p, bl);
 }
 template<class T>
-inline void _decode(std::list<T>& s, bufferlist& bl, int& off) 
+inline void _decode(std::vector<T>& v, bufferlist& bl, int& off)
 {
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  for (int i=0; i<n; i++) {
-    T v;
-    bl.copy(off, sizeof(v), (char*)&v);
-    off += sizeof(v);
-    s.push_back(v);
-  }
-  assert(s.size() == (unsigned)n);
+  __uint32_t n;
+  _decoderaw(n, bl, off);
+  v.resize(n);
+  for (__uint32_t i=0; i<n; i++) 
+    _decode(v[i], bl, off);
 }
 
-
-// map<string,bufferptr>
-inline void _encode(std::map<std::string, bufferptr>& s, bufferlist& bl)
+// map
+template<class T, class U>
+inline void _encode(const std::map<T,U>& m, bufferlist& bl)
 {
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (std::map<std::string, bufferptr>::iterator it = s.begin();
-       it != s.end();
-       it++) {
-    _encode(it->first, bl);
-    _encode(it->second, bl);
-    n--;
+  __uint32_t n = m.size();
+  _encoderaw(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);
   }
-  assert(n==0);
 }
-inline void _decode(std::map<std::string,bufferptr>& s, bufferlist& bl, int& off) 
+template<class T, class U>
+inline void _decode(std::map<T,U>& m, bufferlist& bl, int& off)
 {
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  for (int i=0; i<n; i++) {
-    std::string k;
+  __uint32_t n;
+  _decoderaw(n, bl, off);
+  m.clear();
+  while (n--) {
+    T k;
     _decode(k, bl, off);
-    _decode(s[k], bl, off);
+    _decode(m[k], bl, off);
   }
-  assert(s.size() == (unsigned)n);
 }
 
-
-// map<T,bufferlist>
-template<class T>
-inline void _encode(const std::map<T, bufferlist>& s, bufferlist& bl)
+// hash_map
+template<class T, class U>
+inline void _encode(const __gnu_cxx::hash_map<T,U>& m, bufferlist& bl)
 {
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  //std::cout << "n = " << n << std::endl;
-  for (typename std::map<T, bufferlist>::const_iterator it = s.begin();
-       it != s.end();
-       it++) {
-    T k = it->first;
-    bl.append((char*)&k, sizeof(k));
-    _encode(it->second, bl);
-    n--;
-    //std::cout << "--n = " << n << " after k " << k << std::endl;
+  __uint32_t n = m.size();
+  _encoderaw(n, bl);
+  for (typename __gnu_cxx::hash_map<T,U>::const_iterator p = m.begin(); p != m.end(); ++p) {
+    _encode(p->first, bl);
+    _encode(p->second, bl);
   }
-  assert(n==0);
 }
-template<class T>
-inline void _decode(std::map<T,bufferlist>& s, bufferlist& bl, int& off) 
+template<class T, class U>
+inline void _decode(__gnu_cxx::hash_map<T,U>& m, bufferlist& bl, int& off)
 {
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  for (int i=0; i<n; i++) {
+  __uint32_t n;
+  _decoderaw(n, bl, off);
+  m.clear();
+  while (n--) {
     T k;
-    bl.copy(off, sizeof(k), (char*)&k);
-    off += sizeof(k);
-    bufferlist b;
-    _decode(b, bl, off);
-    s[k] = b;
+    _decode(k, bl, off);
+    _decode(m[k], bl, off);
   }
-  assert(s.size() == (unsigned)n);
 }
 
-// map<string,U>
-template<class U>
-inline void _encode(const std::map<std::string, U>& s, bufferlist& bl)
+// string
+inline void _encode(const std::string& s, bufferlist& bl) 
 {
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (typename std::map<std::string, U>::const_iterator it = s.begin();
-       it != s.end();
-       it++) {
-    ::_encode(it->first, bl);
-    U v = it->second;
-    bl.append((char*)&v, sizeof(v));
-    n--;
-  }
-  assert(n==0);
+  __uint32_t len = s.length();
+  _encoderaw(len, bl);
+  bl.append(s.data(), len);
 }
-template<class U>
-inline void _decode(std::map<std::string,U>& s, bufferlist& bl, int& off) 
+inline void _decode(std::string& s, bufferlist& bl, int& off)
 {
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  for (int i=0; i<n; i++) {
-    std::string k;
-    U v;
-    ::_decode(k, bl, off);
-    bl.copy(off, sizeof(v), (char*)&v);
-    off += sizeof(v);
-    s[k] = v;
-  }
-  assert(s.size() == (unsigned)n);
+  __uint32_t len;
+  _decoderaw(len, bl, off);
+  s = bl.c_str() + off;    // FIXME someday to avoid a huge buffer copy?
+  off += len;
 }
 
-// map<T,set<U>>
-template<class T, class U>
-inline void _encode(const std::map<T, std::set<U> >& s, bufferlist& bl)
-{
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (typename std::map<T, std::set<U> >::const_iterator it = s.begin();
-       it != s.end();
-       it++) {
-    T k = it->first;
-    bl.append((char*)&k, sizeof(k));
-    ::_encode(it->second, bl);
-    n--;
-  }
-  assert(n==0);
-}
-template<class T, class U>
-inline void _decode(std::map<T, std::set<U> >& s, bufferlist& bl, int& off) 
-{
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  for (int i=0; i<n; i++) {
-    T k;
-    bl.copy(off, sizeof(k), (char*)&k);
-    off += sizeof(k);
-    ::_decode(s[k], bl, off);
-  }
-  assert(s.size() == (unsigned)n);
-}
-// map<T,list<U>>
-template<class T, class U>
-inline void _encode(const std::map<T, std::list<U> >& s, bufferlist& bl)
+// bufferptr (encapsulated)
+inline void _encode(bufferptr& bp, bufferlist& bl) 
 {
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (typename std::map<T, std::list<U> >::const_iterator it = s.begin();
-       it != s.end();
-       it++) {
-    T k = it->first;
-    bl.append((char*)&k, sizeof(k));
-    ::_encode(it->second, bl);
-    n--;
-  }
-  assert(n==0);
+  __uint32_t len = bp.length();
+  _encoderaw(len, bl);
+  bl.append(bp);
 }
-template<class T, class U>
-inline void _decode(std::map<T, std::list<U> >& s, bufferlist& bl, int& off) 
+inline void _decode(bufferptr& bp, bufferlist& bl, int& off)
 {
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  for (int i=0; i<n; i++) {
-    T k;
-    bl.copy(off, sizeof(k), (char*)&k);
-    off += sizeof(k);
-    ::_decode(s[k], bl, off);
-  }
-  assert(s.size() == (unsigned)n);
-}
+  __uint32_t len;
+  _decoderaw(len, bl, off);
 
+  bufferlist s;
+  s.substr_of(bl, off, len);
+  off += len;
 
-// map<T,U>
-template<class T, class U>
-inline void _encode(const std::map<T, U>& s, bufferlist& bl)
+  if (s.buffers().size() == 1)
+    bp = s.buffers().front();
+  else
+    bp = buffer::copy(s.c_str(), s.length());
+}
+
+// bufferlist (encapsulated)
+inline void _encode(const bufferlist& s, bufferlist& bl) 
 {
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (typename std::map<T, U>::const_iterator it = s.begin();
-       it != s.end();
-       it++) {
-    T k = it->first;
-    U v = it->second;
-    bl.append((char*)&k, sizeof(k));
-    bl.append((char*)&v, sizeof(v));
-    n--;
-  }
-  assert(n==0);
+  __uint32_t len = s.length();
+  _encoderaw(len, bl);
+  bl.append(s);
 }
-template<class T, class U>
-inline void _decode(std::map<T,U>& s, bufferlist& bl, int& off) 
+inline void _decode(bufferlist& s, bufferlist& bl, int& off)
 {
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  for (int i=0; i<n; i++) {
-    T k;
-    bl.copy(off, sizeof(k), (char*)&k);
-    off += sizeof(k);
-    bl.copy(off, sizeof(U), (char*)&s[k]);
-    off += sizeof(U);
-  }
-  assert(s.size() == (unsigned)n);
+  __uint32_t len;
+  _decoderaw(len, bl, off);
+  s.substr_of(bl, off, len);
+  off += len;
 }
 
-// hash_map<T,U>
-template<class T, class U>
-inline void _encode(const __gnu_cxx::hash_map<T, U>& s, bufferlist& bl)
+// base
+template<class T>
+inline void _encode(const T& t, bufferlist& bl)
 {
-  int n = s.size();
-  bl.append((char*)&n, sizeof(n));
-  for (typename __gnu_cxx::hash_map<T, U>::const_iterator it = s.begin();
-       it != s.end();
-       it++) {
-    T k = it->first;
-    U v = it->second;
-    bl.append((char*)&k, sizeof(k));
-    bl.append((char*)&v, sizeof(v));
-    n--;
-  }
-  assert(n==0);
+  _encoderaw(t, bl);
 }
-template<class T, class U>
-inline void _decode(__gnu_cxx::hash_map<T,U>& s, bufferlist& bl, int& off) 
+template<class T>
+inline void _decode(T& t, bufferlist& bl, int& off)
 {
-  s.clear();
-  int n;
-  bl.copy(off, sizeof(n), (char*)&n);
-  off += sizeof(n);
-  for (int i=0; i<n; i++) {
-    T k;
-    bl.copy(off, sizeof(k), (char*)&k);
-    off += sizeof(k);
-    bl.copy(off, sizeof(U), (char*)&s[k]);
-    off += sizeof(U);
-  }
-  assert(s.size() == (unsigned)n);
+  _decoderaw(t, bl, off);
 }
 
 
 
-
 #endif