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]