You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by je...@apache.org on 2020/06/03 21:11:46 UTC

[thrift] branch master updated: THRIFT-5114 Simplified reallocation of TMemoryBuffer Client: cpp Patch: Mario Emmenlauer

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

jensg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/thrift.git


The following commit(s) were added to refs/heads/master by this push:
     new eac4d0c  THRIFT-5114 Simplified reallocation of TMemoryBuffer Client: cpp Patch: Mario Emmenlauer
eac4d0c is described below

commit eac4d0c79a5fc550fb61bc18f20d3b5aae8f6e7f
Author: Mario Emmenlauer <ma...@emmenlauer.de>
AuthorDate: Thu Feb 20 17:12:29 2020 +0100

    THRIFT-5114 Simplified reallocation of TMemoryBuffer
    Client: cpp
    Patch: Mario Emmenlauer
    
    This closes #2030
---
 lib/cpp/src/thrift/transport/TBufferTransports.cpp | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/lib/cpp/src/thrift/transport/TBufferTransports.cpp b/lib/cpp/src/thrift/transport/TBufferTransports.cpp
index 534067f..329d220 100644
--- a/lib/cpp/src/thrift/transport/TBufferTransports.cpp
+++ b/lib/cpp/src/thrift/transport/TBufferTransports.cpp
@@ -361,16 +361,18 @@ void TMemoryBuffer::ensureCanWrite(uint32_t len) {
   }
 
   // Grow the buffer as necessary.
-  uint64_t new_size = bufferSize_;
-  while (len > avail) {
-    new_size = new_size > 0 ? new_size * 2 : 1;
-    if (new_size > maxBufferSize_) {
-      throw TTransportException(TTransportException::BAD_ARGS,
-                                "Internal buffer size overflow");
-    }
-    avail = available_write() + (static_cast<uint32_t>(new_size) - bufferSize_);
+  const uint32_t current_used = bufferSize_ - avail;
+  const uint32_t required_buffer_size = len + current_used;
+  if (required_buffer_size > maxBufferSize_) {
+    throw TTransportException(TTransportException::BAD_ARGS,
+                              "Internal buffer size overflow when requesting a buffer of size " + std::to_string(required_buffer_size));
   }
 
+  // Always grow to the next bigger power of two:
+  const double suggested_buffer_size = std::exp2(std::ceil(std::log2(required_buffer_size)));
+  // Unless the power of two exceeds maxBufferSize_:
+  const uint64_t new_size = static_cast<uint64_t>((std::min)(suggested_buffer_size, static_cast<double>(maxBufferSize_)));
+
   // Allocate into a new pointer so we don't bork ours if it fails.
   auto* new_buffer = static_cast<uint8_t*>(std::realloc(buffer_, static_cast<std::size_t>(new_size)));
   if (new_buffer == nullptr) {
@@ -381,6 +383,7 @@ void TMemoryBuffer::ensureCanWrite(uint32_t len) {
   rBound_ = new_buffer + (rBound_ - buffer_);
   wBase_ = new_buffer + (wBase_ - buffer_);
   wBound_ = new_buffer + new_size;
+  // Note: with realloc() we do not need to free the previous buffer:
   buffer_ = new_buffer;
   bufferSize_ = static_cast<uint32_t>(new_size);
 }