diff options
author | Alan Conway <aconway@apache.org> | 2007-11-10 02:43:26 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2007-11-10 02:43:26 +0000 |
commit | cb2305a66ae4b3616d7323a336463e1efb4c6ee5 (patch) | |
tree | 3af7474087a9ddc03d3a5ff954869332ca02c90a /cpp/src | |
parent | 20e71deb3cfbeda6962a5e6411bfce11ba65aacf (diff) | |
download | qpid-python-cb2305a66ae4b3616d7323a336463e1efb4c6ee5.tar.gz |
Replace vector in AMQHeaderBody with boost::optional.
Eliminates 40% of allocs.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@593721 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/qpid/framing/AMQHeaderBody.cpp | 37 | ||||
-rw-r--r-- | cpp/src/qpid/framing/AMQHeaderBody.h | 115 |
2 files changed, 61 insertions, 91 deletions
diff --git a/cpp/src/qpid/framing/AMQHeaderBody.cpp b/cpp/src/qpid/framing/AMQHeaderBody.cpp index 8e02f6827f..724c288705 100644 --- a/cpp/src/qpid/framing/AMQHeaderBody.cpp +++ b/cpp/src/qpid/framing/AMQHeaderBody.cpp @@ -22,36 +22,21 @@ #include "qpid/Exception.h" #include "qpid/log/Statement.h" -qpid::framing::AMQHeaderBody::AMQHeaderBody() {} - -qpid::framing::AMQHeaderBody::~AMQHeaderBody() {} - -uint32_t qpid::framing::AMQHeaderBody::size() const{ - CalculateSize visitor; - for_each(properties.begin(), properties.end(), boost::apply_visitor(visitor)); - return visitor.totalSize(); +uint32_t qpid::framing::AMQHeaderBody::size() const { + return properties.size(); } void qpid::framing::AMQHeaderBody::encode(Buffer& buffer) const { - Encode visitor(buffer); - for_each(properties.begin(), properties.end(), boost::apply_visitor(visitor)); + properties.encode(buffer); } -void qpid::framing::AMQHeaderBody::decode(Buffer& buffer, uint32_t size){ +void qpid::framing::AMQHeaderBody::decode(Buffer& buffer, uint32_t size) { uint32_t limit = buffer.available() - size; while (buffer.available() > limit + 2) { uint32_t len = buffer.getLong(); uint16_t type = buffer.getShort(); - //The following switch could be generated as the number of options increases: - switch(type) { - case MessageProperties::TYPE: - decode(MessageProperties(), buffer, len - 2); - break; - case DeliveryProperties::TYPE: - decode(DeliveryProperties(), buffer, len - 2); - break; - default: - //TODO: should just skip over them keeping them for later dispatch as is + if (!properties.decode(buffer, len, type)) { + // TODO: should just skip & keep for later dispatch. throw Exception(QPID_MSG("Unexpected property type: " << type)); } } @@ -60,9 +45,8 @@ void qpid::framing::AMQHeaderBody::decode(Buffer& buffer, uint32_t size){ uint64_t qpid::framing::AMQHeaderBody::getContentLength() const { const MessageProperties* mProps = get<MessageProperties>(); - if (mProps) { + if (mProps) return mProps->getContentLength(); - } return 0; } @@ -70,7 +54,10 @@ void qpid::framing::AMQHeaderBody::print(std::ostream& out) const { out << "header (" << size() << " bytes)"; out << "; properties={"; - Print visitor(out); - for_each(properties.begin(), properties.end(), boost::apply_visitor(visitor)); + properties.print(out); out << "}"; } + +void qpid::framing::AMQHeaderBody::accept(AMQBodyConstVisitor& v) const { + v.visit(*this); +} diff --git a/cpp/src/qpid/framing/AMQHeaderBody.h b/cpp/src/qpid/framing/AMQHeaderBody.h index 460bd2d69e..1cc9d80ea1 100644 --- a/cpp/src/qpid/framing/AMQHeaderBody.h +++ b/cpp/src/qpid/framing/AMQHeaderBody.h @@ -1,3 +1,6 @@ +#ifndef QPID_FRAMING_AMQHEADERBODY_H +#define QPID_FRAMING_AMQHEADERBODY_H + /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -24,66 +27,58 @@ #include "qpid/framing/DeliveryProperties.h" #include "qpid/framing/MessageProperties.h" #include <iostream> -#include <vector> -#include <boost/variant.hpp> -#include <boost/variant/get.hpp> -#ifndef _AMQHeaderBody_ -#define _AMQHeaderBody_ +#include <boost/optional.hpp> + namespace qpid { namespace framing { class AMQHeaderBody : public AMQBody { - typedef std::vector< boost::variant<DeliveryProperties, MessageProperties> > PropertyList; - - PropertyList properties; - - template <class T> void decode(T t, Buffer& b, uint32_t size) { - t.decodeStructBody(b, size); - properties.push_back(t); - } - - class Encode : public boost::static_visitor<> { - Buffer& buffer; - public: - Encode(Buffer& b) : buffer(b) {} - - template <class T> void operator()(T& t) const { - t.encode(buffer); + template <class T> struct OptProps { boost::optional<T> props; }; + template <class Base, class T> + struct PropSet : public Base, public OptProps<T> { + uint32_t size() const { + const boost::optional<T>& p=this->OptProps<T>::props; + return (p ? p->size() : 0) + Base::size(); } - - }; - - class CalculateSize : public boost::static_visitor<> { - uint32_t size; - public: - CalculateSize() : size(0) {} - - template <class T> void operator()(T& t) { - size += t.size(); + void encode(Buffer& buffer) const { + const boost::optional<T>& p=this->OptProps<T>::props; + if (p) p->encode(buffer); + Base::encode(buffer); } - - uint32_t totalSize() { - return size; + bool decode(Buffer& buffer, uint32_t size, uint16_t type) { + boost::optional<T>& p=this->OptProps<T>::props; + if (type == T::TYPE) { + p=T(); + p->decodeStructBody(buffer, size); + return true; + } + else + return Base::decode(buffer, size, type); } + void print(std::ostream& out) const { + const boost::optional<T>& p=this->OptProps<T>::props; + Base::print(out << p); + } }; - class Print : public boost::static_visitor<> { - std::ostream& out; - public: - Print(std::ostream& o) : out(o) {} - - template <class T> void operator()(T& t) { - out << t; - } + struct Empty { + uint32_t size() const { return 0; } + void encode(Buffer&) const {}; + bool decode(Buffer&, uint32_t, uint16_t) const { return false; }; + void print(std::ostream&) const {} }; + // Could use boost::mpl::fold to construct a larger set. + typedef PropSet<PropSet<Empty, DeliveryProperties>, + MessageProperties> Properties; + + Properties properties; + public: - AMQHeaderBody(); - ~AMQHeaderBody(); inline uint8_t type() const { return HEADER_BODY; } uint32_t size() const; @@ -91,33 +86,21 @@ public: void decode(Buffer& buffer, uint32_t size); uint64_t getContentLength() const; void print(std::ostream& out) const; + void accept(AMQBodyConstVisitor&) const; - void accept(AMQBodyConstVisitor& v) const { v.visit(*this); } - - template <class T> T* get(bool create) { - for (PropertyList::iterator i = properties.begin(); i != properties.end(); i++) { - T* p = boost::get<T>(&(*i)); - if (p) return p; - } - if (create) { - properties.push_back(T()); - return boost::get<T>(&(properties.back())); - } else { - return 0; - } + template <class T> T* get(bool create) { + boost::optional<T>& p=properties.OptProps<T>::props; + if (create && !p) p=T(); + return p.get_ptr(); } - template <class T> const T* get() const { - for (PropertyList::const_iterator i = properties.begin(); i != properties.end(); i++) { - const T* p = boost::get<T>(&(*i)); - if (p) return p; - } - return 0; + template <class T> const T* get() const { + return properties.OptProps<T>::props.get_ptr(); } }; -} -} +}} + -#endif +#endif /*!QPID_FRAMING_AMQHEADERBODY_H*/ |