summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2007-11-10 02:43:26 +0000
committerAlan Conway <aconway@apache.org>2007-11-10 02:43:26 +0000
commitcb2305a66ae4b3616d7323a336463e1efb4c6ee5 (patch)
tree3af7474087a9ddc03d3a5ff954869332ca02c90a /cpp/src
parent20e71deb3cfbeda6962a5e6411bfce11ba65aacf (diff)
downloadqpid-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.cpp37
-rw-r--r--cpp/src/qpid/framing/AMQHeaderBody.h115
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*/