You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2007/11/10 03:43:29 UTC
svn commit: r593721 - in /incubator/qpid/trunk/qpid/cpp/src/qpid/framing:
AMQHeaderBody.cpp AMQHeaderBody.h
Author: aconway
Date: Fri Nov 9 18:43:26 2007
New Revision: 593721
URL: http://svn.apache.org/viewvc?rev=593721&view=rev
Log:
Replace vector in AMQHeaderBody with boost::optional.
Eliminates 40% of allocs.
Modified:
incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQHeaderBody.cpp
incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQHeaderBody.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQHeaderBody.cpp?rev=593721&r1=593720&r2=593721&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQHeaderBody.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQHeaderBody.cpp Fri Nov 9 18:43:26 2007
@@ -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 @@
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 @@
{
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);
}
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQHeaderBody.h?rev=593721&r1=593720&r2=593721&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQHeaderBody.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/AMQHeaderBody.h Fri Nov 9 18:43:26 2007
@@ -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);
- }
-
- };
-
- class CalculateSize : public boost::static_visitor<> {
- uint32_t size;
- public:
- CalculateSize() : size(0) {}
-
- template <class T> void operator()(T& t) {
- size += t.size();
+ 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();
+ }
+ void encode(Buffer& buffer) const {
+ const boost::optional<T>& p=this->OptProps<T>::props;
+ if (p) p->encode(buffer);
+ Base::encode(buffer);
+ }
+ 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;
}
-
- uint32_t totalSize() {
- return size;
+ 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 @@
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*/