]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common: introduce contiguous_filler to optimize ENCODE_START.
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Thu, 20 Sep 2018 20:28:12 +0000 (16:28 -0400)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Sat, 6 Oct 2018 10:45:38 +0000 (12:45 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
src/common/buffer.cc
src/include/buffer.h
src/include/encoding.h
src/test/bufferlist.cc

index de8b2f34f022df4b47d0cff360b9d034202974dc..d172bc0939faa0f69a58e06095b4b5fbf94eef7e 100644 (file)
@@ -1674,7 +1674,7 @@ using namespace ceph;
     }
   }
 
-  buffer::list::iterator buffer::list::append_hole(const unsigned len)
+  buffer::list::contiguous_filler buffer::list::append_hole(const unsigned len)
   {
     if (unlikely(append_buffer.unused_tail_length() < len)) {
       // make a new append_buffer.  fill out a complete page, factoring in
@@ -1690,8 +1690,7 @@ using namespace ceph;
     append_buffer.set_length(append_buffer.length() + len);
     append(append_buffer, append_buffer.length() - len, len);
 
-    const auto lastbuf = std::prev(std::end(_buffers));
-    return { this, length() - len, lastbuf, lastbuf->length() - len };
+    return { std::prev(std::end(_buffers))->end_c_str() - len };
   }
 
   void buffer::list::prepend_zero(unsigned len)
index f4ae5a744ed7aefc21a8ceb33c4329c74a5d0bb3..332e67a72f32153dff94ef3a6ede0f5ab3b9f442 100644 (file)
@@ -650,6 +650,22 @@ namespace buffer CEPH_BUFFER_API {
       return contiguous_appender(this, len, deep);
     }
 
+    class contiguous_filler {
+      friend buffer::list;
+      char* pos;
+
+      contiguous_filler(char* const pos) : pos(pos) {}
+
+    public:
+      void copy_in(const unsigned len, const char* const src) {
+       memcpy(pos, src, len);
+       pos += len;
+      }
+    };
+    // The contiguous_filler is supposed to be not costlier than a single
+    // pointer. Keep it dumb, please.
+    static_assert(sizeof(contiguous_filler) == sizeof(char*));
+
     class page_aligned_appender {
       bufferlist *pbl;
       unsigned min_alloc;
@@ -913,7 +929,7 @@ namespace buffer CEPH_BUFFER_API {
     void append(const ptr& bp, unsigned off, unsigned len);
     void append(const list& bl);
     void append(std::istream& in);
-    iterator append_hole(unsigned len);
+    contiguous_filler append_hole(unsigned len);
     void append_zero(unsigned len);
     void prepend_zero(unsigned len);
     
index a343443cda09f4d8d1c0366212c80e7ef2ab56fd..1ad2f9d0ff70d28c6c6ad2def97303c07f9f4560 100644 (file)
@@ -1206,14 +1206,13 @@ decode(std::array<T, N>& v, bufferlist::const_iterator& p)
  *
  */
 #define ENCODE_START(v, compat, bl)                         \
-  using ::ceph::encode;                                             \
-  __u8 struct_v = v, struct_compat = compat;                \
+  __u8 struct_v = v;                                         \
+  __u8 struct_compat = compat;                              \
   ceph_le32 struct_len;                                             \
-  encode(struct_v, (bl));                                   \
-  ::ceph::buffer::list::iterator struct_compat_it =         \
-    (bl).append_hole(sizeof(struct_compat));                \
-  ::ceph::buffer::list::iterator struct_len_it =            \
-    (bl).append_hole(sizeof(struct_len));                   \
+  auto filler = (bl).append_hole(sizeof(struct_v) +         \
+    sizeof(struct_compat) + sizeof(struct_len));            \
+  const auto starting_bl_len = (bl).length();               \
+  using ::ceph::encode;                                             \
   do {
 
 /**
@@ -1222,14 +1221,16 @@ decode(std::array<T, N>& v, bufferlist::const_iterator& p)
  * @param bl bufferlist we were encoding to
  * @param new_struct_compat struct-compat value to use
  */
-#define ENCODE_FINISH_NEW_COMPAT(bl, new_struct_compat)                        \
-  } while (false);                                                     \
-  struct_len = (bl).length() - struct_len_it.get_off() - sizeof(struct_len); \
-  struct_len_it.copy_in(4, (char *)&struct_len);                       \
-  if (new_struct_compat) {                                             \
-    struct_compat = new_struct_compat;                                 \
-  }                                                                    \
-  struct_compat_it.copy_in(1, (char *)&struct_compat);
+#define ENCODE_FINISH_NEW_COMPAT(bl, new_struct_compat)      \
+  } while (false);                                           \
+  if (new_struct_compat) {                                   \
+    struct_compat = new_struct_compat;                       \
+  }                                                          \
+  struct_len = (bl).length() - starting_bl_len;              \
+  filler.copy_in(sizeof(struct_v), (char *)&struct_v);       \
+  filler.copy_in(sizeof(struct_compat),                             \
+    (char *)&struct_compat);                                \
+  filler.copy_in(sizeof(struct_len), (char *)&struct_len);
 
 #define ENCODE_FINISH(bl) ENCODE_FINISH_NEW_COMPAT(bl, 0)
 
index b1af1b6c4c8aa1ff45fdd67548bc55759fcef0c7..a856c205eab8141ac97950c76cbe3c10fcca5cf1 100644 (file)
@@ -2113,7 +2113,7 @@ TEST(BufferList, append) {
 TEST(BufferList, append_hole) {
   {
     bufferlist bl;
-    auto iter = bl.append_hole(1);
+    auto filler = bl.append_hole(1);
     EXPECT_EQ((unsigned)1, bl.get_num_buffers());
     EXPECT_EQ((unsigned)1, bl.length());
 
@@ -2122,8 +2122,7 @@ TEST(BufferList, append_hole) {
     EXPECT_EQ((unsigned)3, bl.length());
 
     const char a = 'A';
-    EXPECT_EQ((unsigned)2, bl.length() - iter.get_off() - sizeof(a));
-    iter.copy_in((unsigned)1, &a);
+    filler.copy_in((unsigned)1, &a);
     EXPECT_EQ((unsigned)3, bl.length());
 
     EXPECT_EQ(0, ::memcmp("ABC", bl.c_str(), 3));
@@ -2135,7 +2134,7 @@ TEST(BufferList, append_hole) {
     EXPECT_EQ((unsigned)1, bl.get_num_buffers());
     EXPECT_EQ((unsigned)1, bl.length());
 
-    auto iter = bl.append_hole(1);
+    auto filler = bl.append_hole(1);
     EXPECT_EQ((unsigned)1, bl.get_num_buffers());
     EXPECT_EQ((unsigned)2, bl.length());
 
@@ -2144,8 +2143,7 @@ TEST(BufferList, append_hole) {
     EXPECT_EQ((unsigned)3, bl.length());
 
     const char b = 'B';
-    EXPECT_EQ((unsigned)1, bl.length() - iter.get_off() - sizeof(b));
-    iter.copy_in((unsigned)1, &b);
+    filler.copy_in((unsigned)1, &b);
     EXPECT_EQ((unsigned)3, bl.length());
 
     EXPECT_EQ(0, ::memcmp("ABC", bl.c_str(), 3));