You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2012/03/06 00:55:50 UTC

svn commit: r1297290 - in /qpid/trunk/qpid/cpp: include/qpid/framing/FieldTable.h src/qpid/framing/FieldTable.cpp

Author: astitcher
Date: Mon Mar  5 23:55:50 2012
New Revision: 1297290

URL: http://svn.apache.org/viewvc?rev=1297290&view=rev
Log:
QPID-3883: Using application headers in messages causes a very large slowdown
Some more tidying up of the FieldTable implementation:
- implement a more selective copy constructor
- keep the encoded data in case we are used again
- more careful raw bytes cache flush

Modified:
    qpid/trunk/qpid/cpp/include/qpid/framing/FieldTable.h
    qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp

Modified: qpid/trunk/qpid/cpp/include/qpid/framing/FieldTable.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/include/qpid/framing/FieldTable.h?rev=1297290&r1=1297289&r2=1297290&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/include/qpid/framing/FieldTable.h (original)
+++ qpid/trunk/qpid/cpp/include/qpid/framing/FieldTable.h Mon Mar  5 23:55:50 2012
@@ -58,7 +58,9 @@ class FieldTable
     typedef ValueMap::value_type value_type;
 
     QPID_COMMON_EXTERN FieldTable();
-    // Compiler default copy, assignment and destructor are fine
+    QPID_COMMON_EXTERN FieldTable(const FieldTable&);
+    QPID_COMMON_EXTERN FieldTable& operator=(const FieldTable&);
+    // Compiler default destructor fine
     QPID_COMMON_EXTERN uint32_t encodedSize() const;
     QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
     QPID_COMMON_EXTERN void decode(Buffer& buffer);

Modified: qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp?rev=1297290&r1=1297289&r2=1297290&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp Mon Mar  5 23:55:50 2012
@@ -36,6 +36,25 @@ FieldTable::FieldTable() :
 {
 }
 
+FieldTable::FieldTable(const FieldTable& ft) :
+    cachedBytes(ft.cachedBytes),
+    cachedSize(ft.cachedSize)
+{
+    // Only copy the values if we have no raw data
+    // - copying the map is expensive and we can
+    //   reconstruct it if necessary from the raw data
+    if (!cachedBytes && !ft.values.empty()) values = ft.values;
+}
+
+FieldTable& FieldTable::operator=(const FieldTable& ft)
+{
+    FieldTable nft(ft);
+    values.swap(nft.values);
+    cachedBytes.swap(nft.cachedBytes);
+    cachedSize = nft.cachedSize;
+    return (*this);
+}
+
 uint32_t FieldTable::encodedSize() const {
     if (cachedSize != 0) {
         return cachedSize;
@@ -211,18 +230,23 @@ void FieldTable::encode(Buffer& buffer) 
     if (cachedBytes) {
         buffer.putRawData(&cachedBytes[0], cachedSize);
     } else {
+        uint32_t p = buffer.getPosition();
         buffer.putLong(encodedSize() - 4);
         buffer.putLong(values.size());
         for (ValueMap::const_iterator i = values.begin(); i!=values.end(); ++i) {
             buffer.putShortString(i->first);
             i->second->encode(buffer);
         }
+        // Now create raw bytes in case we are used again
+        cachedSize = buffer.getPosition() - p;
+        cachedBytes = boost::shared_array<uint8_t>(new uint8_t[cachedSize]);
+        buffer.setPosition(p);
+        buffer.getRawData(&cachedBytes[0], cachedSize);
     }
 }
 
 // Decode lazily - just record the raw bytes until we need them
 void FieldTable::decode(Buffer& buffer){
-    clear();
     if (buffer.available() < 4)
         throw IllegalArgumentException(QPID_MSG("Not enough data for field table."));
     uint32_t p = buffer.getPosition();
@@ -232,6 +256,8 @@ void FieldTable::decode(Buffer& buffer){
         if ((available < len) || (available < 4))
             throw IllegalArgumentException(QPID_MSG("Not enough data for field table."));
     }
+    // Throw away previous stored values
+    values.clear();
     // Copy data into our buffer
     cachedBytes = boost::shared_array<uint8_t>(new uint8_t[len + 4]);
     cachedSize = len + 4;
@@ -260,16 +286,12 @@ void FieldTable::realDecode() const
             values[name] = ValuePtr(value);
         }
     }
-    cachedSize = len + 4;
-    // We've done the delayed decoding throw away the raw data
-    // (later on we may find a way to keep this and avoid some
-    // other allocations)
-    cachedBytes.reset();
 }
 
 void FieldTable::flushRawCache() const
 {
-    cachedBytes.reset();
+    // Avoid recreating shared array unless we actually have one.
+    if (cachedBytes) cachedBytes.reset();
     cachedSize = 0;
 }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org