You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by di...@apache.org on 2019/02/15 09:47:21 UTC

[rocketmq-client-cpp] branch master updated: Optimize: optimize memory copy in MemoryBlock by move constructor and move assignment. (#70)

This is an automated email from the ASF dual-hosted git repository.

dinglei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-client-cpp.git


The following commit(s) were added to refs/heads/master by this push:
     new 3b8509e  Optimize: optimize memory copy in MemoryBlock by move constructor and move assignment. (#70)
3b8509e is described below

commit 3b8509e79e1e733d43765921d2a4976b9a27f297
Author: James <yw...@hotmail.com>
AuthorDate: Fri Feb 15 17:47:17 2019 +0800

    Optimize: optimize memory copy in MemoryBlock by move constructor and move assignment. (#70)
    
    Optimize: optimize memory copy of MemoryBlock by move constructor and move assignment.
---
 src/common/dataBlock.cpp     | 364 +++++++++++++++++++------------------
 src/common/dataBlock.h       | 414 ++++++++++++++++++++++---------------------
 src/consumer/PullResultExt.h |  97 +++++-----
 3 files changed, 451 insertions(+), 424 deletions(-)

diff --git a/src/common/dataBlock.cpp b/src/common/dataBlock.cpp
index 7f42f95..4195f2b 100755
--- a/src/common/dataBlock.cpp
+++ b/src/common/dataBlock.cpp
@@ -13,177 +13,193 @@
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
-*/
-#include "dataBlock.h"
-#include <algorithm>
-
-namespace rocketmq {
-MemoryBlock::MemoryBlock() : size(0), data(NULL) {}
-
-MemoryBlock::MemoryBlock(const int initialSize, const bool initialiseToZero)
-    : size(0), data(NULL) {
-  if (initialSize > 0) {
-    size = initialSize;
-    data = static_cast<char*>(initialiseToZero
-                                  ? std::calloc(initialSize, sizeof(char))
-                                  : std::malloc(initialSize * sizeof(char)));
-  }
-}
-
-MemoryBlock::MemoryBlock(const void* const dataToInitialiseFrom,
-                         const size_t sizeInBytes)
-    : size(sizeInBytes), data(NULL) {
-  if (size > 0) {
-    data = static_cast<char*>(std::malloc(size * sizeof(char)));
-
-    if (dataToInitialiseFrom != NULL) memcpy(data, dataToInitialiseFrom, size);
-  }
-}
-
-MemoryBlock::MemoryBlock(const MemoryBlock& other)
-    : size(other.size), data(NULL) {
-  if (size > 0) {
-    data = static_cast<char*>(std::malloc(size * sizeof(char)));
-    memcpy(data, other.data, size);
-  }
-}
-
-MemoryBlock::~MemoryBlock() { std::free(data); }
-
-MemoryBlock& MemoryBlock::operator=(const MemoryBlock& other) {
-  if (this != &other) {
-    setSize(other.size, false);
-    memcpy(data, other.data, size);
-  }
-
-  return *this;
-}
-
-//==============================================================================
-bool MemoryBlock::operator==(const MemoryBlock& other) const {
-  return matches(other.data, other.size);
-}
-
-bool MemoryBlock::operator!=(const MemoryBlock& other) const {
-  return !operator==(other);
-}
-
-bool MemoryBlock::matches(const void* dataToCompare, int dataSize) const {
-  return size == dataSize && memcmp(data, dataToCompare, size) == 0;
-}
-
-//==============================================================================
-// this will resize the block to this size
-void MemoryBlock::setSize(const int newSize, const bool initialiseToZero) {
-  if (size != newSize) {
-    if (newSize <= 0) {
-      reset();
-    } else {
-      if (data != NULL) {
-        data = static_cast<char*>(
-            data == NULL ? std::malloc(newSize * sizeof(char))
-                         : std::realloc(data, newSize * sizeof(char)));
-
-        if (initialiseToZero && (newSize > size))
-          memset(data + size, 0, newSize - size);
-      } else {
-        std::free(data);
-        data = static_cast<char*>(initialiseToZero
-                                      ? std::calloc(newSize, sizeof(char))
-                                      : std::malloc(newSize * sizeof(char)));
-      }
-
-      size = newSize;
-    }
-  }
-}
-
-void MemoryBlock::reset() {
-  std::free(data);
-  data = NULL;
-  size = 0;
-}
-
-void MemoryBlock::ensureSize(const int minimumSize,
-                             const bool initialiseToZero) {
-  if (size < minimumSize) setSize(minimumSize, initialiseToZero);
-}
-
-//==============================================================================
-void MemoryBlock::fillWith(const int value) { memset(data, (int)value, size); }
-
-void MemoryBlock::append(const void* const srcData, const int numBytes) {
-  if (numBytes > 0) {
-    const int oldSize = size;
-    setSize(size + numBytes);
-    memcpy(data + oldSize, srcData, numBytes);
-  }
-}
-
-void MemoryBlock::replaceWith(const void* const srcData, const int numBytes) {
-  if (numBytes > 0) {
-    setSize(numBytes);
-    memcpy(data, srcData, numBytes);
-  }
-}
-
-void MemoryBlock::insert(const void* const srcData, const int numBytes,
-                         int insertPosition) {
-  if (numBytes > 0) {
-    insertPosition = std::min(insertPosition, size);
-    const int trailingDataSize = size - insertPosition;
-    setSize(size + numBytes, false);
-
-    if (trailingDataSize > 0)
-      memmove(data + insertPosition + numBytes, data + insertPosition,
-              trailingDataSize);
-
-    memcpy(data + insertPosition, srcData, numBytes);
-  }
-}
-
-void MemoryBlock::removeSection(const int startByte,
-                                const int numBytesToRemove) {
-  if (startByte + numBytesToRemove >= size) {
-    setSize(startByte);
-  } else if (numBytesToRemove > 0) {
-    memmove(data + startByte, data + startByte + numBytesToRemove,
-            size - (startByte + numBytesToRemove));
-
-    setSize(size - numBytesToRemove);
-  }
-}
-
-void MemoryBlock::copyFrom(const void* const src, int offset, int num) {
-  const char* d = static_cast<const char*>(src);
-
-  if (offset < 0) {
-    d -= offset;
-    num += (size_t)-offset;
-    offset = 0;
-  }
-
-  if ((size_t)offset + num > (unsigned int)size) num = size - (size_t)offset;
-
-  if (num > 0) memcpy(data + offset, d, num);
-}
-
-void MemoryBlock::copyTo(void* const dst, int offset, int num) const {
-  char* d = static_cast<char*>(dst);
-
-  if (offset < 0) {
-    memset(d, 0, (size_t)-offset);
-    d -= offset;
-    num -= (size_t)-offset;
-    offset = 0;
-  }
-
-  if ((size_t)offset + num > (unsigned int)size) {
-    const int newNum = (size_t)size - (size_t)offset;
-    memset(d + newNum, 0, num - newNum);
-    num = newNum;
-  }
-
-  if (num > 0) memcpy(d, data + offset, num);
-}
-}
+*/
+#include "dataBlock.h"
+#include <algorithm>
+
+namespace rocketmq {
+
+MemoryBlock::MemoryBlock() : size(0), data(NULL) {}
+
+MemoryBlock::MemoryBlock(const int initialSize, const bool initialiseToZero)
+    : size(0), data(NULL) {
+  if (initialSize > 0) {
+    size = initialSize;
+    data = static_cast<char *>(initialiseToZero
+                               ? std::calloc(initialSize, sizeof(char))
+                               : std::malloc(initialSize * sizeof(char)));
+  }
+}
+
+MemoryBlock::MemoryBlock(const void *const dataToInitialiseFrom, const size_t sizeInBytes)
+    : size(sizeInBytes), data(NULL) {
+  if (size > 0) {
+    data = static_cast<char *>(std::malloc(size * sizeof(char)));
+
+    if (dataToInitialiseFrom != NULL) memcpy(data, dataToInitialiseFrom, size);
+  }
+}
+
+MemoryBlock::MemoryBlock(const MemoryBlock &other) : size(other.size), data(NULL) {
+  if (size > 0) {
+    data = static_cast<char *>(std::malloc(size * sizeof(char)));
+    memcpy(data, other.data, size);
+  }
+}
+
+MemoryBlock::MemoryBlock(MemoryBlock &&other) : size(other.size), data(other.data) {
+  other.size = 0;
+  other.data = NULL;
+}
+
+MemoryBlock::~MemoryBlock() { std::free(data); }
+
+MemoryBlock &MemoryBlock::operator=(const MemoryBlock &other) {
+  if (this != &other) {
+    setSize(other.size, false);
+    memcpy(data, other.data, size);
+  }
+
+  return *this;
+}
+
+MemoryBlock &MemoryBlock::operator=(MemoryBlock &&other) {
+  if (this != &other) {
+    std::free(data);
+
+    size = other.size;
+    data = other.data;
+
+    other.size = 0;
+    other.data = NULL;
+  }
+
+  return *this;
+}
+
+//==============================================================================
+bool MemoryBlock::operator==(const MemoryBlock &other) const {
+  return matches(other.data, other.size);
+}
+
+bool MemoryBlock::operator!=(const MemoryBlock &other) const {
+  return !operator==(other);
+}
+
+bool MemoryBlock::matches(const void *dataToCompare, int dataSize) const {
+  return size == dataSize && memcmp(data, dataToCompare, size) == 0;
+}
+
+//==============================================================================
+// this will resize the block to this size
+void MemoryBlock::setSize(const int newSize, const bool initialiseToZero) {
+  if (size != newSize) {
+    if (newSize <= 0) {
+      reset();
+    } else {
+      if (data != NULL) {
+        data = static_cast<char *>(
+            data == NULL ? std::malloc(newSize * sizeof(char))
+                         : std::realloc(data, newSize * sizeof(char)));
+
+        if (initialiseToZero && (newSize > size))
+          memset(data + size, 0, newSize - size);
+      } else {
+        std::free(data);
+        data = static_cast<char *>(initialiseToZero
+                                   ? std::calloc(newSize, sizeof(char))
+                                   : std::malloc(newSize * sizeof(char)));
+      }
+
+      size = newSize;
+    }
+  }
+}
+
+void MemoryBlock::reset() {
+  std::free(data);
+  data = NULL;
+  size = 0;
+}
+
+void MemoryBlock::ensureSize(const int minimumSize, const bool initialiseToZero) {
+  if (size < minimumSize) setSize(minimumSize, initialiseToZero);
+}
+
+//==============================================================================
+void MemoryBlock::fillWith(const int value) {
+  memset(data, (int) value, size);
+}
+
+void MemoryBlock::append(const void *const srcData, const int numBytes) {
+  if (numBytes > 0) {
+    const int oldSize = size;
+    setSize(size + numBytes);
+    memcpy(data + oldSize, srcData, numBytes);
+  }
+}
+
+void MemoryBlock::replaceWith(const void *const srcData, const int numBytes) {
+  if (numBytes > 0) {
+    setSize(numBytes);
+    memcpy(data, srcData, numBytes);
+  }
+}
+
+void MemoryBlock::insert(const void *const srcData, const int numBytes, int insertPosition) {
+  if (numBytes > 0) {
+    insertPosition = std::min(insertPosition, size);
+    const int trailingDataSize = size - insertPosition;
+    setSize(size + numBytes, false);
+
+    if (trailingDataSize > 0)
+      memmove(data + insertPosition + numBytes, data + insertPosition,
+              trailingDataSize);
+
+    memcpy(data + insertPosition, srcData, numBytes);
+  }
+}
+
+void MemoryBlock::removeSection(const int startByte, const int numBytesToRemove) {
+  if (startByte + numBytesToRemove >= size) {
+    setSize(startByte);
+  } else if (numBytesToRemove > 0) {
+    memmove(data + startByte, data + startByte + numBytesToRemove, size - (startByte + numBytesToRemove));
+
+    setSize(size - numBytesToRemove);
+  }
+}
+
+void MemoryBlock::copyFrom(const void *const src, int offset, int num) {
+  const char *d = static_cast<const char *>(src);
+
+  if (offset < 0) {
+    d -= offset;
+    num += (size_t) -offset;
+    offset = 0;
+  }
+
+  if ((size_t) offset + num > (unsigned int) size) num = size - (size_t) offset;
+
+  if (num > 0) memcpy(data + offset, d, num);
+}
+
+void MemoryBlock::copyTo(void *const dst, int offset, int num) const {
+  char *d = static_cast<char *>(dst);
+
+  if (offset < 0) {
+    memset(d, 0, (size_t) -offset);
+    d -= offset;
+    num -= (size_t) -offset;
+    offset = 0;
+  }
+
+  if ((size_t) offset + num > (unsigned int) size) {
+    const int newNum = (size_t) size - (size_t) offset;
+    memset(d + newNum, 0, num - newNum);
+    num = newNum;
+  }
+
+  if (num > 0) memcpy(d, data + offset, num);
+}
+}
diff --git a/src/common/dataBlock.h b/src/common/dataBlock.h
index 17930f7..88099b7 100755
--- a/src/common/dataBlock.h
+++ b/src/common/dataBlock.h
@@ -1,205 +1,209 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef __DATABLOCK_H__
-#define __DATABLOCK_H__
-
-#include <stddef.h>
-#include <stdint.h>
-#include <algorithm>
-#include <cstdlib>
-#include <cstring>
-
-#include "RocketMQClient.h"
-
-namespace rocketmq {
-
-class ROCKETMQCLIENT_API MemoryBlock {
- public:
-  //==============================================================================
-  /** Create an uninitialised block with 0 size. */
-  MemoryBlock();
-
-  /** Creates a memory block with a given initial size.
-
-      @param initialSize          the size of block to create
-      @param initialiseToZero     whether to clear the memory or just leave it
-     uninitialised
-  */
-  MemoryBlock(const int initialSize, bool initialiseToZero = false);
-
-  /** Creates a memory block using a copy of a block of data.
-
-      @param dataToInitialiseFrom     some data to copy into this block
-      @param sizeInBytes              how much space to use
-  */
-  MemoryBlock(const void* dataToInitialiseFrom, size_t sizeInBytes);
-
-  /** Creates a copy of another memory block. */
-  MemoryBlock(const MemoryBlock&);
-
-  /** Destructor. */
-  ~MemoryBlock();
-
-  /** Copies another memory block onto this one.
-      This block will be resized and copied to exactly match the other one.
-  */
-  MemoryBlock& operator=(const MemoryBlock&);
-
-  //==============================================================================
-  /** Compares two memory blocks.
-      @returns true only if the two blocks are the same size and have identical
-     contents.
-  */
-  bool operator==(const MemoryBlock& other) const;
-
-  /** Compares two memory blocks.
-      @returns true if the two blocks are different sizes or have different
-     contents.
-  */
-  bool operator!=(const MemoryBlock& other) const;
-
-  //==============================================================================
-  /** Returns a void pointer to the data.
-
-      Note that the pointer returned will probably become invalid when the
-      block is resized.
-  */
-  char* getData() const { return data; }
-
-  /** Returns a byte from the memory block.
-      This returns a reference, so you can also use it to set a byte.
-  */
-  template <typename Type>
-  char& operator[](const Type offset) const {
-    return data[offset];
-  }
-
-  /** Returns true if the data in this MemoryBlock matches the raw bytes
-   * passed-in. */
-  bool matches(const void* data, int dataSize) const;
-
-  //==============================================================================
-  /** Returns the block's current allocated size, in bytes. */
-  int getSize() const { return size; }
-
-  /** Resizes the memory block.
-
-      Any data that is present in both the old and new sizes will be retained.
-      When enlarging the block, the new space that is allocated at the end can
-     either be
-      cleared, or left uninitialised.
-
-      @param newSize                      the new desired size for the block
-      @param initialiseNewSpaceToZero     if the block gets enlarged, this
-     determines
-                                          whether to clear the new section or
-     just leave it
-                                          uninitialised
-      @see ensureSize
-  */
-  void setSize(const int newSize, bool initialiseNewSpaceToZero = false);
-
-  /** Increases the block's size only if it's smaller than a given size.
-
-      @param minimumSize                  if the block is already bigger than
-     this size, no action
-                                          will be taken; otherwise it will be
-     increased to this size
-      @param initialiseNewSpaceToZero     if the block gets enlarged, this
-     determines
-                                          whether to clear the new section or
-     just leave it
-                                          uninitialised
-      @see setSize
-  */
-  void ensureSize(const int minimumSize, bool initialiseNewSpaceToZero = false);
-
-  /** Frees all the blocks data, setting its size to 0. */
-  void reset();
-
-  //==============================================================================
-  /** Fills the entire memory block with a repeated byte value.
-      This is handy for clearing a block of memory to zero.
-  */
-  void fillWith(int valueToUse);
-
-  /** Adds another block of data to the end of this one.
-      The data pointer must not be null. This block's size will be increased
-     accordingly.
-  */
-  void append(const void* data, int numBytes);
-
-  /** Resizes this block to the given size and fills its contents from the
-     supplied buffer.
-      The data pointer must not be null.
-  */
-  void replaceWith(const void* data, int numBytes);
-
-  /** Inserts some data into the block.
-      The dataToInsert pointer must not be null. This block's size will be
-     increased accordingly.
-      If the insert position lies outside the valid range of the block, it will
-     be clipped to
-      within the range before being used.
-  */
-  void insert(const void* dataToInsert, int numBytesToInsert,
-              int insertPosition);
-
-  /** Chops out a section  of the block.
-
-      This will remove a section of the memory block and close the gap around
-     it,
-      shifting any subsequent data downwards and reducing the size of the block.
-
-      If the range specified goes beyond the size of the block, it will be
-     clipped.
-  */
-  void removeSection(int startByte, int numBytesToRemove);
-
-  //==============================================================================
-  /** Copies data into this MemoryBlock from a memory address.
-
-      @param srcData              the memory location of the data to copy into
-     this block
-      @param destinationOffset    the offset in this block at which the data
-     being copied should begin
-      @param numBytes             how much to copy in (if this goes beyond the
-     size of the memory block,
-                                  it will be clipped so not to do anything
-     nasty)
-  */
-  void copyFrom(const void* srcData, int destinationOffset, int numBytes);
-
-  /** Copies data from this MemoryBlock to a memory address.
-
-      @param destData         the memory location to write to
-      @param sourceOffset     the offset within this block from which the copied
-     data will be read
-      @param numBytes         how much to copy (if this extends beyond the
-     limits of the memory block,
-                              zeros will be used for that portion of the data)
-  */
-  void copyTo(void* destData, int sourceOffset, int numBytes) const;
-
- private:
-  //==============================================================================
-  int size;
-  char* data;
-};
-}
-
-#endif
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef __DATABLOCK_H__
+#define __DATABLOCK_H__
+
+#include <stddef.h>
+#include <stdint.h>
+#include <algorithm>
+#include <cstdlib>
+#include <cstring>
+
+#include "RocketMQClient.h"
+
+namespace rocketmq {
+
+class ROCKETMQCLIENT_API MemoryBlock {
+ public:
+  //==============================================================================
+  /** Create an uninitialised block with 0 size. */
+  MemoryBlock();
+
+  /** Creates a memory block with a given initial size.
+
+      @param initialSize          the size of block to create
+      @param initialiseToZero     whether to clear the memory or just leave it
+     uninitialised
+  */
+  MemoryBlock(const int initialSize, bool initialiseToZero = false);
+
+  /** Creates a memory block using a copy of a block of data.
+
+      @param dataToInitialiseFrom     some data to copy into this block
+      @param sizeInBytes              how much space to use
+  */
+  MemoryBlock(const void *dataToInitialiseFrom, size_t sizeInBytes);
+
+  /** Creates a copy of another memory block. */
+  MemoryBlock(const MemoryBlock &);
+
+  MemoryBlock(MemoryBlock &&);
+
+  /** Destructor. */
+  ~MemoryBlock();
+
+  /** Copies another memory block onto this one.
+      This block will be resized and copied to exactly match the other one.
+  */
+  MemoryBlock &operator=(const MemoryBlock &);
+
+  MemoryBlock &operator=(MemoryBlock &&);
+
+  //==============================================================================
+  /** Compares two memory blocks.
+      @returns true only if the two blocks are the same size and have identical
+     contents.
+  */
+  bool operator==(const MemoryBlock &other) const;
+
+  /** Compares two memory blocks.
+      @returns true if the two blocks are different sizes or have different
+     contents.
+  */
+  bool operator!=(const MemoryBlock &other) const;
+
+  //==============================================================================
+  /** Returns a void pointer to the data.
+
+      Note that the pointer returned will probably become invalid when the
+      block is resized.
+  */
+  char *getData() const { return data; }
+
+  /** Returns a byte from the memory block.
+      This returns a reference, so you can also use it to set a byte.
+  */
+  template<typename Type>
+  char &operator[](const Type offset) const {
+    return data[offset];
+  }
+
+  /** Returns true if the data in this MemoryBlock matches the raw bytes
+   * passed-in. */
+  bool matches(const void *data, int dataSize) const;
+
+  //==============================================================================
+  /** Returns the block's current allocated size, in bytes. */
+  int getSize() const { return size; }
+
+  /** Resizes the memory block.
+
+      Any data that is present in both the old and new sizes will be retained.
+      When enlarging the block, the new space that is allocated at the end can
+     either be
+      cleared, or left uninitialised.
+
+      @param newSize                      the new desired size for the block
+      @param initialiseNewSpaceToZero     if the block gets enlarged, this
+     determines
+                                          whether to clear the new section or
+     just leave it
+                                          uninitialised
+      @see ensureSize
+  */
+  void setSize(const int newSize, bool initialiseNewSpaceToZero = false);
+
+  /** Increases the block's size only if it's smaller than a given size.
+
+      @param minimumSize                  if the block is already bigger than
+     this size, no action
+                                          will be taken; otherwise it will be
+     increased to this size
+      @param initialiseNewSpaceToZero     if the block gets enlarged, this
+     determines
+                                          whether to clear the new section or
+     just leave it
+                                          uninitialised
+      @see setSize
+  */
+  void ensureSize(const int minimumSize, bool initialiseNewSpaceToZero = false);
+
+  /** Frees all the blocks data, setting its size to 0. */
+  void reset();
+
+  //==============================================================================
+  /** Fills the entire memory block with a repeated byte value.
+      This is handy for clearing a block of memory to zero.
+  */
+  void fillWith(int valueToUse);
+
+  /** Adds another block of data to the end of this one.
+      The data pointer must not be null. This block's size will be increased
+     accordingly.
+  */
+  void append(const void *data, int numBytes);
+
+  /** Resizes this block to the given size and fills its contents from the
+     supplied buffer.
+      The data pointer must not be null.
+  */
+  void replaceWith(const void *data, int numBytes);
+
+  /** Inserts some data into the block.
+      The dataToInsert pointer must not be null. This block's size will be
+     increased accordingly.
+      If the insert position lies outside the valid range of the block, it will
+     be clipped to
+      within the range before being used.
+  */
+  void insert(const void *dataToInsert, int numBytesToInsert,
+              int insertPosition);
+
+  /** Chops out a section  of the block.
+
+      This will remove a section of the memory block and close the gap around
+     it,
+      shifting any subsequent data downwards and reducing the size of the block.
+
+      If the range specified goes beyond the size of the block, it will be
+     clipped.
+  */
+  void removeSection(int startByte, int numBytesToRemove);
+
+  //==============================================================================
+  /** Copies data into this MemoryBlock from a memory address.
+
+      @param srcData              the memory location of the data to copy into
+     this block
+      @param destinationOffset    the offset in this block at which the data
+     being copied should begin
+      @param numBytes             how much to copy in (if this goes beyond the
+     size of the memory block,
+                                  it will be clipped so not to do anything
+     nasty)
+  */
+  void copyFrom(const void *srcData, int destinationOffset, int numBytes);
+
+  /** Copies data from this MemoryBlock to a memory address.
+
+      @param destData         the memory location to write to
+      @param sourceOffset     the offset within this block from which the copied
+     data will be read
+      @param numBytes         how much to copy (if this extends beyond the
+     limits of the memory block,
+                              zeros will be used for that portion of the data)
+  */
+  void copyTo(void *destData, int sourceOffset, int numBytes) const;
+
+ private:
+  //==============================================================================
+  int size;
+  char *data;
+};
+}
+
+#endif
diff --git a/src/consumer/PullResultExt.h b/src/consumer/PullResultExt.h
index ac6b8e9..07a8c94 100755
--- a/src/consumer/PullResultExt.h
+++ b/src/consumer/PullResultExt.h
@@ -1,45 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "PullResult.h"
-#include "UtilAll.h"
-#include "dataBlock.h"
-
-namespace rocketmq {
-/**
- * ֻ���ڲ�ʹ�ã������⹫��
- */
-//<!***************************************************************************
-class PullResultExt : public PullResult {
- public:
-  PullResultExt(PullStatus pullStatus, int64 nextBeginOffset, int64 minOffset,
-                int64 maxOffset, int suggestWhichBrokerId,
-                const MemoryBlock& messageBinary)
-      : PullResult(pullStatus, nextBeginOffset, minOffset, maxOffset),
-        suggestWhichBrokerId(suggestWhichBrokerId),
-        msgMemBlock(messageBinary) {}
-  PullResultExt(PullStatus pullStatus, int64 nextBeginOffset, int64 minOffset,
-                int64 maxOffset, int suggestWhichBrokerId)
-      : PullResult(pullStatus, nextBeginOffset, minOffset, maxOffset),
-        suggestWhichBrokerId(suggestWhichBrokerId) {}
-  virtual ~PullResultExt() {}
-
- public:
-  int suggestWhichBrokerId;
-  MemoryBlock msgMemBlock;
-};
-
-}  //<!end namespace;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "PullResult.h"
+#include "UtilAll.h"
+#include "dataBlock.h"
+
+namespace rocketmq {
+/**
+ * use internal only
+ */
+//<!***************************************************************************
+class PullResultExt : public PullResult {
+ public:
+  PullResultExt(PullStatus pullStatus, int64 nextBeginOffset, int64 minOffset,
+                int64 maxOffset, int suggestWhichBrokerId, const MemoryBlock &messageBinary)
+      : PullResult(pullStatus, nextBeginOffset, minOffset, maxOffset),
+        suggestWhichBrokerId(suggestWhichBrokerId),
+        msgMemBlock(messageBinary) {}
+
+  PullResultExt(PullStatus pullStatus, int64 nextBeginOffset, int64 minOffset,
+                int64 maxOffset, int suggestWhichBrokerId, MemoryBlock &&messageBinary)
+      : PullResult(pullStatus, nextBeginOffset, minOffset, maxOffset),
+        suggestWhichBrokerId(suggestWhichBrokerId),
+        msgMemBlock(std::forward<MemoryBlock>(messageBinary)) {}
+
+  PullResultExt(PullStatus pullStatus, int64 nextBeginOffset, int64 minOffset,
+                int64 maxOffset, int suggestWhichBrokerId)
+      : PullResult(pullStatus, nextBeginOffset, minOffset, maxOffset),
+        suggestWhichBrokerId(suggestWhichBrokerId) {}
+
+  virtual ~PullResultExt() {}
+
+ public:
+  int suggestWhichBrokerId;
+  MemoryBlock msgMemBlock;
+};
+
+}  //<!end namespace;