From: g0dil Date: Wed, 5 May 2010 15:23:04 +0000 (+0000) Subject: Packets: Implement PacketRegistry priority support X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=4d90b955bf3590e215488395d1c9cec827476e07;p=senf.git Packets: Implement PacketRegistry priority support git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1621 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Packets/80221Bundle/MIHPacket.cc b/senf/Packets/80221Bundle/MIHPacket.cc index e3f4389..3f549c5 100644 --- a/senf/Packets/80221Bundle/MIHPacket.cc +++ b/senf/Packets/80221Bundle/MIHPacket.cc @@ -72,7 +72,8 @@ prefix_ senf::PacketInterpreterBase::factory_t senf::MIHPacketType::nextPacketTy { if (p.data().size() < initSize()) return no_factory(); - PkReg_Entry const * e (PacketRegistry::lookup( p->messageId(), nothrow )); + PacketRegistry::Entry const * e ( + PacketRegistry::lookup( p->messageId(), nothrow )); return e ? e->factory() : MIHGenericPayloadPacket::factory(); } diff --git a/senf/Packets/DefaultBundle/LlcSnapPacket.cc b/senf/Packets/DefaultBundle/LlcSnapPacket.cc index 8b09238..78762db 100644 --- a/senf/Packets/DefaultBundle/LlcSnapPacket.cc +++ b/senf/Packets/DefaultBundle/LlcSnapPacket.cc @@ -50,8 +50,8 @@ prefix_ void senf::LlcSnapPacketType::dump(packet p, std::ostream & os) prefix_ senf::PacketInterpreterBase::factory_t senf::LlcSnapPacketType::nextPacketType(packet p) { if (p->type_length() >= 1536) { - PkReg_Entry const * e; - e = PacketRegistry::lookup( p->type_length(), nothrow ); + PacketRegistry::Entry const * e ( + PacketRegistry::lookup( p->type_length(), nothrow )); return e ? e->factory() : no_factory(); } if (p->type_length() <= 1500) diff --git a/senf/Packets/MPEGDVBBundle/SNDUPacket.cc b/senf/Packets/MPEGDVBBundle/SNDUPacket.cc index 2aa6253..6f4e8ea 100644 --- a/senf/Packets/MPEGDVBBundle/SNDUPacket.cc +++ b/senf/Packets/MPEGDVBBundle/SNDUPacket.cc @@ -57,12 +57,18 @@ prefix_ senf::PacketInterpreterBase::factory_t senf::SNDUPacketType::nextPacketT { if (p.data().size() < 8) return no_factory(); - PkReg_Entry const * e; - if (p->type() < 1536) - e = PacketRegistry::lookup( p->type(), nothrow ); - else - e = PacketRegistry::lookup( p->type(), nothrow ); - return e ? e->factory() : no_factory(); + senf::PacketInterpreterBase::factory_t f (no_factory()); + if (p->type() < 1536) { + PacketRegistry::Entry const * e ( + PacketRegistry::lookup( p->type(), nothrow )); + if (e) f = e->factory(); + } + else { + PacketRegistry::Entry const * e ( + PacketRegistry::lookup( p->type(), nothrow )); + if (e) f = e->factory(); + } + return f; } prefix_ senf::PacketInterpreterBase::optional_range diff --git a/senf/Packets/PacketRegistry.cc b/senf/Packets/PacketRegistry.cc index a4fa3dc..da8a5bb 100644 --- a/senf/Packets/PacketRegistry.cc +++ b/senf/Packets/PacketRegistry.cc @@ -31,9 +31,6 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ senf::PkReg_Entry::~PkReg_Entry() -{} - prefix_ senf::detail::PacketRegistryImplBase::~PacketRegistryImplBase() {} diff --git a/senf/Packets/PacketRegistry.ct b/senf/Packets/PacketRegistry.ct index 0048815..40afa89 100644 --- a/senf/Packets/PacketRegistry.ct +++ b/senf/Packets/PacketRegistry.ct @@ -37,24 +37,49 @@ ///////////////////////////////ct.p//////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// -// senf::detail::PkReg_EntryImpl +// senf::detail::PacketRegistryImpl::Entry +template +prefix_ senf::detail::PacketRegistryImpl::Entry::Entry(KeyType const & key_, + int priority_) + : key (key_), priority (priority_) +{} + +template +prefix_ senf::detail::PacketRegistryImpl::Entry::~Entry() +{} + +/////////////////////////////////////////////////////////////////////////// +// senf::detail::PacketRegistryImpl::EntryImpl + +template +template +prefix_ senf::detail::PacketRegistryImpl::EntryImpl:: +EntryImpl(KeyType const & key, int priority) + : Entry (key, priority) +{} + +template template -prefix_ senf::PacketInterpreterBase::factory_t senf::detail::PkReg_EntryImpl::factory() +prefix_ senf::Packet::factory_t +senf::detail::PacketRegistryImpl::EntryImpl::factory() const { return PacketType::factory(); } +template template -prefix_ std::string senf::detail::PkReg_EntryImpl::name() +prefix_ std::string senf::detail::PacketRegistryImpl::EntryImpl::name() const { return prettyName(typeid(PacketType)); } +template template -prefix_ senf::TypeIdValue senf::detail::PkReg_EntryImpl::typeIdValue() +prefix_ std::type_info const & +senf::detail::PacketRegistryImpl::EntryImpl::type() const { return typeid(PacketType); @@ -76,87 +101,71 @@ senf::PacketRegistry::registry() template template -prefix_ void senf::detail::PacketRegistryImpl::registerPacket(key_t key) -{ -#ifndef SENF_DEBUG - registry_.insert(std::make_pair(key, Entry_ptr(new detail::PkReg_EntryImpl()))); - reverseRegistry_.insert(std::make_pair(senf::typeIdValue(), key)); -#else - bool isUnique ( - registry_.insert( - std::make_pair(key, Entry_ptr(new detail::PkReg_EntryImpl()))).second); - // If this assertion fails, a Packet was registered with an already known key - SENF_ASSERT( isUnique ); - bool isNew ( - reverseRegistry_.insert( - std::make_pair(senf::typeIdValue(), key)).second); - // If this assertion fails, the same Packet was registered with two different keys - SENF_ASSERT( isNew ); -#endif +prefix_ void senf::detail::PacketRegistryImpl::registerPacket(key_t key, int priority) +{ + SENF_ASSERT(registry_.insert( + typename Entry::ptr(new EntryImpl(key,priority))).second); } template template prefix_ void senf::detail::PacketRegistryImpl::unregisterPacket() { - typename PacketMap::iterator i (registry_.find(key(typeIdValue()))); - typename ReversePacketMap::iterator j (reverseRegistry_.find(typeIdValue())); - if (i != registry_.end()) - registry_.erase(i); - if (j != reverseRegistry_.end()) - reverseRegistry_.erase(j); + registry_.template get().erase(typeid(PacketType)); } template -prefix_ void senf::detail::PacketRegistryImpl::unregisterPacket(key_t key) +prefix_ void senf::detail::PacketRegistryImpl::unregisterPacket(key_t key, int priority) { - typename PacketMap::iterator i (registry_.find(key)); - if (i == registry_.end()) - throw PacketTypeNotRegisteredException(); - typename ReversePacketMap::iterator j (reverseRegistry_.find(i->second->typeIdValue())); - registry_.erase(i); - if (j != reverseRegistry_.end()) - reverseRegistry_.erase(j); + // Why doesn't this work: + // registry_.erase(boost::make_tuple(key,priority)); + typename Registry::iterator i (registry_.find(boost::make_tuple(key,priority))); + if (i != registry_.end()) + registry_.erase(i); } template prefix_ typename senf::detail::PacketRegistryImpl::key_t senf::detail::PacketRegistryImpl::key(senf::TypeIdValue const & type) { - typename ReversePacketMap::iterator i (reverseRegistry_.find(type)); - if (i==reverseRegistry_.end()) + boost::optional k (key(type,true)); + if (! k) throw PacketTypeNotRegisteredException(); - return i->second; + return *k; } template prefix_ boost::optional::key_t> senf::detail::PacketRegistryImpl::key(senf::TypeIdValue const & type, bool) { - typename ReversePacketMap::iterator i (reverseRegistry_.find(type)); - if (i==reverseRegistry_.end()) + typedef typename Registry::template index::type TypeIndex; + TypeIndex const & typeIndex (registry_.template get()); + typename TypeIndex::const_iterator i (typeIndex.find(type.id())); + if (i == typeIndex.end()) return boost::optional(); - return i->second; + return (*i)->key; } template prefix_ typename senf::detail::PacketRegistryImpl::Entry const & senf::detail::PacketRegistryImpl::lookup(key_t key) { - typename PacketMap::iterator i (registry_.find(key)); - if (i==registry_.end()) + Entry const * e (lookup(key, true)); + if (!e) throw PacketTypeNotRegisteredException(); - return *(i->second); + return *e; } template prefix_ typename senf::detail::PacketRegistryImpl::Entry const * senf::detail::PacketRegistryImpl::lookup(key_t key, bool) { - typename PacketMap::iterator i (registry_.find(key)); - if (i==registry_.end()) + typedef typename Registry::template index::type KeyIndex; + KeyIndex const & keyIndex (registry_.template get()); + typename KeyIndex::const_iterator i (keyIndex.lower_bound(key)); + if (i == keyIndex.end() || (*i)->key != key) return 0; - return i->second.get(); + return i->get(); } template @@ -170,12 +179,13 @@ template prefix_ void senf::detail::PacketRegistryImpl::v_dump(std::ostream & os) const { - typename PacketMap::const_iterator i (registry_.begin()); - typename PacketMap::const_iterator const i_end (registry_.end()); - for (; i != i_end; ++i) { - std::string n (i->second->name()); - senf::detail::DumpKey::dump(i->first, os); - os << ' ' << n.substr(21,n.size()-22) << "\n"; + typedef typename Registry::template index::type KeyIndex; + KeyIndex const & keyIndex (registry_.template get()); + for (typename KeyIndex::iterator i (keyIndex.begin()), i_end (keyIndex.end()); + i != i_end; ++i) { + std::string n ((*i)->name()); + senf::detail::DumpKey::dump((*i)->key, os); + os << ' ' << std::setw(6) << (*i)->priority << ' ' << n.substr(21,n.size()-22) << '\n'; } } @@ -183,7 +193,6 @@ template prefix_ void senf::detail::PacketRegistryImpl::v_clear() { registry_.clear(); - reverseRegistry_.clear(); } /////////////////////////////////////////////////////////////////////////// diff --git a/senf/Packets/PacketRegistry.cti b/senf/Packets/PacketRegistry.cti index a99c59b..dd19e9a 100644 --- a/senf/Packets/PacketRegistry.cti +++ b/senf/Packets/PacketRegistry.cti @@ -103,14 +103,15 @@ senf::PacketRegistry::key(Packet const & packet, NoThrow_t) } template -prefix_ senf::PkReg_Entry const & senf::PacketRegistry::lookup(typename Tag::key_t key) +prefix_ typename senf::PacketRegistry::Entry const & +senf::PacketRegistry::lookup(typename Tag::key_t key) { return registry().lookup(key); } template -prefix_ senf::PkReg_Entry const * senf::PacketRegistry::lookup(typename Tag::key_t key, - NoThrow_t) +prefix_ typename senf::PacketRegistry::Entry const * +senf::PacketRegistry::lookup(typename Tag::key_t key, NoThrow_t) { return registry().lookup(key,true); } @@ -141,8 +142,7 @@ prefix_ typename senf::detail::PacketRegistryImpl::iterator senf::detail::PacketRegistryImpl::begin() const { - return boost::make_transform_iterator( - registry_.begin(), ::__gnu_cxx::select1st()); + return registry_.begin(); } template @@ -150,8 +150,7 @@ prefix_ typename senf::detail::PacketRegistryImpl::iterator senf::detail::PacketRegistryImpl::end() const { - return boost::make_transform_iterator( - registry_.end(), ::__gnu_cxx::select1st()); + return registry_.end(); } ///////////////////////////////PacketRegistry..e/////////////////////////////////////// diff --git a/senf/Packets/PacketRegistry.hh b/senf/Packets/PacketRegistry.hh index e766914..beb3384 100644 --- a/senf/Packets/PacketRegistry.hh +++ b/senf/Packets/PacketRegistry.hh @@ -91,6 +91,7 @@ namespace senf { { public: typedef typename detail::PacketRegistryImpl::iterator iterator; + typedef typename detail::PacketRegistryImpl::Entry Entry; /** \brief Statically register a packet type in a PacketRegistry @@ -180,13 +181,13 @@ namespace senf { \throws PacketTypeNotRegistered if the \a key is not found in the registry \return %Packet entry for given \a key */ - static PkReg_Entry const & lookup(typename Tag::key_t key); + static Entry const & lookup(typename Tag::key_t key); /** \brief Lookup a packet by it's key \return Pointer to packet entry for given \a key or 0, if the key is not found in the registry. */ - static PkReg_Entry const * lookup(typename Tag::key_t key, NoThrow_t); + static Entry const * lookup(typename Tag::key_t key, NoThrow_t); /** \brief Beginning iterator to list of registered keys */ diff --git a/senf/Packets/PacketRegistry.ih b/senf/Packets/PacketRegistry.ih index a1d66ba..e2b0e48 100644 --- a/senf/Packets/PacketRegistry.ih +++ b/senf/Packets/PacketRegistry.ih @@ -29,6 +29,11 @@ // Custom includes #include #include +#include +#include +#include +#include +#include #include #include #include @@ -36,34 +41,12 @@ ///////////////////////////////ih.p//////////////////////////////////////// namespace senf { - - /** \brief Registry entry - - Value returned by a registry lookup - */ - struct PkReg_Entry - : public intrusive_refcount - { - virtual ~PkReg_Entry(); - virtual Packet::factory_t factory() const = 0; - ///< Get factory of the registered packet type - virtual std::string name() const = 0; - virtual TypeIdValue typeIdValue() const = 0; - }; - namespace detail { - /** \brief Internal: Registry entry implementation for a specific packet type - - \internal - */ - template - struct PkReg_EntryImpl - : public PkReg_Entry + struct TypeInfoCompare { - virtual Packet::factory_t factory() const; - virtual std::string name() const; - virtual TypeIdValue typeIdValue() const ; + bool operator()(std::type_info const & a, std::type_info const & b) const + { return a.before(b); } }; /** \brief Internal: Registry implementation base-class and registry of registries @@ -99,19 +82,61 @@ namespace detail { { public: typedef KeyType key_t; - typedef PkReg_Entry Entry; + + struct Entry : public intrusive_refcount + { + typedef boost::intrusive_ptr ptr; + + Entry(KeyType const & key_, int priority_); + virtual ~Entry(); + + virtual Packet::factory_t factory() const = 0; + + virtual std::string name() const = 0; + virtual std::type_info const & type() const = 0; + + KeyType key; + int priority; + }; private: - typedef boost::intrusive_ptr Entry_ptr; - typedef std::map PacketMap; - typedef std::map ReversePacketMap; + struct ByKey {}; + struct ByType {}; + + struct RegistryIndices + : public boost::multi_index::indexed_by< + boost::multi_index::ordered_unique< + boost::multi_index::tag, + boost::multi_index::composite_key< + Entry, + boost::multi_index::member, + boost::multi_index::member >, + boost::multi_index::composite_key_compare< + std::less, + std::greater > >, + boost::multi_index::ordered_unique< + boost::multi_index::tag, + boost::multi_index::mem_fun, + TypeInfoCompare> > + {}; + + typedef boost::multi_index_container Registry; + + template + struct EntryImpl : public Entry + { + EntryImpl(KeyType const & key, int priority); + + virtual Packet::factory_t factory() const; + virtual std::string name() const; + virtual std::type_info const & type() const; + }; public: /////////////////////////////////////////////////////////////////////////// // Types - typedef boost::transform_iterator< ::__gnu_cxx::select1st, - typename PacketMap::const_iterator > iterator; + typedef typename Registry::template index::type::const_iterator iterator; /////////////////////////////////////////////////////////////////////////// ///\name Structors and default members @@ -123,11 +148,11 @@ namespace detail { /////////////////////////////////////////////////////////////////////////// template - void registerPacket(key_t key); + void registerPacket(key_t key, int priority=0); template void unregisterPacket(); - void unregisterPacket(key_t key); + void unregisterPacket(key_t key, int priority=0); key_t key(senf::TypeIdValue const & type); boost::optional key(senf::TypeIdValue const & type, bool); @@ -145,8 +170,7 @@ namespace detail { virtual void v_dump(std::ostream & os) const; virtual void v_clear(); - PacketMap registry_; - ReversePacketMap reverseRegistry_; + Registry registry_; }; template ::is_integer> diff --git a/senf/Packets/PacketRegistry.test.cc b/senf/Packets/PacketRegistry.test.cc index ddb1088..321e19a 100644 --- a/senf/Packets/PacketRegistry.test.cc +++ b/senf/Packets/PacketRegistry.test.cc @@ -83,14 +83,28 @@ SENF_AUTO_UNIT_TEST(packetRegistry_test) BOOST_CHECK( PacketRegistry::lookup(1u, senf::nothrow) ); unsigned elts1[] = { 1u, 2u }; - BOOST_CHECK_EQUAL_COLLECTIONS( PacketRegistry::begin(), - PacketRegistry::end(), - elts1+0, elts1+sizeof(elts1)/sizeof(elts1[0]) ); + BOOST_CHECK_EQUAL_COLLECTIONS( + boost::make_transform_iterator( + PacketRegistry::begin(), + boost::multi_index::member::Entry, unsigned, + &senf::PacketRegistry::Entry::key>()), + boost::make_transform_iterator( + PacketRegistry::end(), + boost::multi_index::member::Entry, unsigned, + &senf::PacketRegistry::Entry::key>()), + elts1+0, elts1+sizeof(elts1)/sizeof(elts1[0]) ); std::string elts2[] = { "bar", "foo" }; - BOOST_CHECK_EQUAL_COLLECTIONS( PacketRegistry::begin(), - PacketRegistry::end(), - elts2+0, elts2+sizeof(elts2)/sizeof(elts2[0]) ); + BOOST_CHECK_EQUAL_COLLECTIONS( + boost::make_transform_iterator( + PacketRegistry::begin(), + boost::multi_index::member::Entry, std::string, + &senf::PacketRegistry::Entry::key>()), + boost::make_transform_iterator( + PacketRegistry::end(), + boost::multi_index::member::Entry, std::string, + &senf::PacketRegistry::Entry::key>()), + elts2+0, elts2+sizeof(elts2)/sizeof(elts2[0]) ); std::stringstream s; senf::dumpPacketRegistries(s); @@ -98,15 +112,15 @@ SENF_AUTO_UNIT_TEST(packetRegistry_test) contains, (s.str()) ("(anonymous namespace)::BaseTag:\n" - " 0x00000001 ( 1) (....) (anonymous namespace)::FooPacketType\n" - " 0x00000002 ( 2) (....) (anonymous namespace)::BarPacketType\n" + " 0x00000001 ( 1) (....) 0 (anonymous namespace)::FooPacketType\n" + " 0x00000002 ( 2) (....) 0 (anonymous namespace)::BarPacketType\n" "\n")); BOOST_CHECK_PREDICATE( contains, (s.str()) ("(anonymous namespace)::StringTag:\n" - " bar (anonymous namespace)::BarPacketType\n" - " foo (anonymous namespace)::FooPacketType\n" + " bar 0 (anonymous namespace)::BarPacketType\n" + " foo 0 (anonymous namespace)::FooPacketType\n" "\n" )); } @@ -117,14 +131,14 @@ SENF_AUTO_UNIT_TEST(packetRegistry_test) contains, (s.str()) ("(anonymous namespace)::BaseTag:\n" - " 0x00000001 ( 1) (....) (anonymous namespace)::FooPacketType\n" + " 0x00000001 ( 1) (....) 0 (anonymous namespace)::FooPacketType\n" "\n")); BOOST_CHECK_PREDICATE( contains, (s.str()) ("(anonymous namespace)::StringTag:\n" - " bar (anonymous namespace)::BarPacketType\n" - " foo (anonymous namespace)::FooPacketType\n" + " bar 0 (anonymous namespace)::BarPacketType\n" + " foo 0 (anonymous namespace)::FooPacketType\n" "\n" )); SENF_CHECK_NO_THROW( PacketRegistry::unregisterPacket(1u) ); @@ -140,7 +154,7 @@ SENF_AUTO_UNIT_TEST(packetRegistry_test) contains, (s.str()) ("(anonymous namespace)::StringTag:\n" - " foo (anonymous namespace)::FooPacketType\n" + " foo 0 (anonymous namespace)::FooPacketType\n" "\n" )); } } diff --git a/senf/Packets/PacketType.cti b/senf/Packets/PacketType.cti index 1b7e693..fe4bdce 100644 --- a/senf/Packets/PacketType.cti +++ b/senf/Packets/PacketType.cti @@ -83,7 +83,8 @@ senf::PacketTypeMixin::key(Packet const & p) template prefix_ senf::PacketTypeBase::factory_t senf::PacketTypeMixin::lookup(key_t key) { - PkReg_Entry const * entry (PacketRegistry::lookup( key, senf::nothrow )); + typename PacketRegistry::Entry const * entry ( + PacketRegistry::lookup( key, senf::nothrow )); return entry ? entry->factory() : PacketTypeBase::no_factory(); }