Author: astitcher
Date: Tue Apr  3 14:28:06 2012
New Revision: 1308933

URL: http://svn.apache.org/viewvc?rev=1308933&view=rev
Log:
QPID-3883: Using application headers in messages causes a very large slowdown
Optimise copying field tables a little more, by encoding them as
we copy them instead of copying the value map.

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

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=1308933&r1=1308932&r2=1308933&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp Tue Apr  3 14:28:06 2012
@@ -69,7 +69,28 @@ FieldTable::FieldTable(const FieldTable&
         newBytes = true;
         return;
     }
-    if (!ft.values.empty()) values = ft.values;
+    // In practice Encoding the source field table and only copying
+    // the encoded bytes is faster than copying the whole value map.
+    // (Because we nearly always copy a field table internally before
+    // encoding it to send, but don't change it after the copy)
+    if (!ft.values.empty()) {
+        // Side effect of getting encoded size will cache it in ft.cachedSize
+        ft.cachedBytes = boost::shared_array<uint8_t>(new 
uint8_t[ft.encodedSize()]);
+
+        Buffer buffer((char*)&ft.cachedBytes[0], ft.cachedSize);
+
+        // Cut and paste ahead...
+        buffer.putLong(ft.encodedSize() - 4);
+        buffer.putLong(ft.values.size());
+        for (ValueMap::const_iterator i = ft.values.begin(); 
i!=ft.values.end(); ++i) {
+            buffer.putShortString(i->first);
+            i->second->encode(buffer);
+        }
+
+        cachedBytes = ft.cachedBytes;
+        cachedSize = ft.cachedSize;
+        newBytes = true;
+    }
 }
 
 FieldTable& FieldTable::operator=(const FieldTable& ft)
@@ -254,24 +275,18 @@ bool FieldTable::getDouble(const std::st
 //}
 
 void FieldTable::encode(Buffer& buffer) const {
-    ScopedLock<Mutex> l(lock);
     // If we've still got the input field table
     // we can just copy it directly to the output
     if (cachedBytes) {
+        ScopedLock<Mutex> l(lock);
         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);
     }
 }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to