From: g0dil Date: Wed, 11 Aug 2010 18:30:43 +0000 (+0000) Subject: Packets: Keep annotation registry sorted by type name X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=20c3dbf64b3beed10655dceaee5791680fb25383;p=senf.git Packets: Keep annotation registry sorted by type name git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1677 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Packets/Packet.test.cc b/senf/Packets/Packet.test.cc index e735207..2dafae1 100644 --- a/senf/Packets/Packet.test.cc +++ b/senf/Packets/Packet.test.cc @@ -29,6 +29,7 @@ // Custom includes #include #include +#include #include "Packets.hh" #include @@ -111,7 +112,7 @@ namespace { } struct IntAnnotation { - unsigned value; + boost::uint32_t value; }; std::ostream & operator<<(std::ostream & os, IntAnnotation const & v) @@ -128,7 +129,7 @@ namespace { { ComplexAnnotation() : s(), i() {} std::string s; - int i; + boost::int32_t i; }; std::ostream & operator<<(std::ostream & os, ComplexAnnotation const & v) @@ -343,11 +344,11 @@ SENF_AUTO_UNIT_TEST(packetAnnotation) ss.str(), "SENF_PACKET_ANNOTATION_SLOTS = 8\n" "SENF_PACKET_ANNOTATION_SLOTSIZE = 16\n" - "SLOT TYPE COMPLEX SIZE\n" - " (anonymous namespace)::ComplexEmptyAnnotation yes 1\n" - " (anonymous namespace)::ComplexAnnotation yes 8\n" - " (anonymous namespace)::LargeAnnotation no 32\n" - " 0 (anonymous namespace)::IntAnnotation no 4\n" ); + "TYPE FAST COMPLEX SIZE\n" + "(anonymous namespace)::ComplexAnnotation no yes 8\n" + "(anonymous namespace)::ComplexEmptyAnnotation no yes 1\n" + "(anonymous namespace)::IntAnnotation yes no 4\n" + "(anonymous namespace)::LargeAnnotation no no 32\n" ); #endif } diff --git a/senf/Packets/PacketImpl.cc b/senf/Packets/PacketImpl.cc index 4bb7eee..9444ab7 100644 --- a/senf/Packets/PacketImpl.cc +++ b/senf/Packets/PacketImpl.cc @@ -27,6 +27,8 @@ // Custom includes #include +#include +#include #include #include #include "Packets.hh" @@ -133,25 +135,23 @@ prefix_ void senf::detail::PacketImpl::updateIterators(PacketData * self, differ prefix_ void senf::detail::PacketImpl::dumpAnnotations(std::ostream & os) { - for (AnnotationRegistry::key_t key (AnnotationRegistry::instance().keyBegin()); - key != AnnotationRegistry::instance().keyEnd(); ++key) { - void * antn (annotation(key)); + for (AnnotationRegistry::iterator i (AnnotationRegistry::instance().begin()); + i != AnnotationRegistry::instance().end(); ++i) { + void * antn (annotation(*i)); if (antn) - AnnotationRegistry::instance().dump(key, os, antn); + AnnotationRegistry::instance().dump(*i, os, antn); } } -prefix_ void * senf::detail::PacketImpl::complexAnnotation(AnnotationRegistry::key_t key) +prefix_ void * senf::detail::PacketImpl::complexAnnotation(AnnotationRegistry::key_type key) { - SENF_ASSERT( key<0, "complexAnnotation called with invalid key"); + SENF_ASSERT( key < 0, "complexAnnotation called with invalid key"); #ifdef SENF_PACKET_NO_COMPLEX_ANNOTATIONS return 0; #else - while (complexAnnotations_.size() < ComplexAnnotations::size_type(-key)) - complexAnnotations_.push_back(0); - if (complexAnnotations_.is_null(-key-1)) - return 0; - return complexAnnotations_[-key-1].get(); + return (ComplexAnnotations::size_type(-key-1) >= complexAnnotations_.size() + || complexAnnotations_.is_null(-key-1)) + ? 0 : complexAnnotations_[-key-1].get(); #endif } @@ -161,16 +161,18 @@ prefix_ void * senf::detail::PacketImpl::complexAnnotation(AnnotationRegistry::k prefix_ void senf::detail::AnnotationRegistry::dumpRegistrations(std::ostream & os) { #ifdef SENF_DEBUG - boost::format fmt ("%4.4s %-56.56s %-7.7s %5d\n"); + boost::format fmt ("%-56.56s %-4.4s %-7.7s %5d\n"); os << "SENF_PACKET_ANNOTATION_SLOTS = " << SENF_PACKET_ANNOTATION_SLOTS << "\n" << "SENF_PACKET_ANNOTATION_SLOTSIZE = " << SENF_PACKET_ANNOTATION_SLOTSIZE << "\n"; - os << fmt % "SLOT" % "TYPE" % "COMPLEX" % "SIZE"; - for (key_t key (keyBegin()); key != keyEnd(); ++key) { - std::string nm (name(key)); + os << fmt % "TYPE" % "FAST" % "COMPLEX" % "SIZE"; + + for (Index::const_iterator i (index_.begin()), i_end (index_.end()); i != i_end; ++i) { + key_type key (i->second); + std::string nm (i->first); if (nm.size() > 56) nm.erase(nm.begin(), nm.begin()+nm.size()-32); os << fmt - % (key >= 0 ? senf::str(key) : "") % nm + % (key >= 0 ? "yes" : "no") % (isComplex(key) ? "yes" : "no") % size(key); } diff --git a/senf/Packets/PacketImpl.cci b/senf/Packets/PacketImpl.cci index 8c863d1..63c330c 100644 --- a/senf/Packets/PacketImpl.cci +++ b/senf/Packets/PacketImpl.cci @@ -33,7 +33,7 @@ /////////////////////////////////////////////////////////////////////////// // senf::detail::AnnotationRegistry -prefix_ void senf::detail::AnnotationRegistry::dump(key_t key, std::ostream & os, +prefix_ void senf::detail::AnnotationRegistry::dump(key_type key, std::ostream & os, void * annotation) const { @@ -45,27 +45,41 @@ prefix_ void senf::detail::AnnotationRegistry::dump(key_t key, std::ostream & os } } -prefix_ std::string senf::detail::AnnotationRegistry::name(key_t key) +prefix_ std::string senf::detail::AnnotationRegistry::name(key_type key) const { Registry::const_iterator i (registry_.find(key)); return i == registry_.end() ? "" : i->second->v_name(); } -prefix_ bool senf::detail::AnnotationRegistry::isComplex(key_t key) +prefix_ bool senf::detail::AnnotationRegistry::isComplex(key_type key) const { Registry::const_iterator i (registry_.find(key)); return i != registry_.end() && i->second->v_isComplex(); } -prefix_ unsigned senf::detail::AnnotationRegistry::size(key_t key) +prefix_ unsigned senf::detail::AnnotationRegistry::size(key_type key) const { Registry::const_iterator i (registry_.find(key)); return i == registry_.end() ? 0 : i->second->v_size(); } +prefix_ senf::detail::AnnotationRegistry::iterator senf::detail::AnnotationRegistry::begin() + const +{ + return boost::make_transform_iterator(index_.begin(), + __gnu_cxx::select2nd()); +} + +prefix_ senf::detail::AnnotationRegistry::iterator senf::detail::AnnotationRegistry::end() + const +{ + return boost::make_transform_iterator(index_.end(), + __gnu_cxx::select2nd()); +} + prefix_ senf::detail::AnnotationRegistry::AnnotationRegistry() : simpleAnnotationCount_ (0), complexAnnotationCount_ (0) {} @@ -234,7 +248,7 @@ prefix_ void senf::detail::PacketImpl::release(refcount_t n) // Annotations -prefix_ void * senf::detail::PacketImpl::annotation(AnnotationRegistry::key_t key) +prefix_ void * senf::detail::PacketImpl::annotation(AnnotationRegistry::key_type key) { return key >= 0 ? & simpleAnnotations_[key] : complexAnnotation(key); } diff --git a/senf/Packets/PacketImpl.ct b/senf/Packets/PacketImpl.ct index 7dc7cb9..93a757c 100644 --- a/senf/Packets/PacketImpl.ct +++ b/senf/Packets/PacketImpl.ct @@ -35,16 +35,18 @@ senf::detail::AnnotationRegistry::RegistrationProxy senf::detail::AnnotationRegistry::Entry::proxy_; template -senf::detail::AnnotationRegistry::key_t +senf::detail::AnnotationRegistry::key_type senf::detail::AnnotationRegistry::Entry::key_; template prefix_ void * senf::detail::PacketImpl::complexAnnotation() { - AnnotationRegistry::key_t key (AnnotationRegistry::lookup()); + AnnotationRegistry::key_type key (AnnotationRegistry::lookup()); void * rv (complexAnnotation(key)); #ifndef SENF_PACKET_NO_COMPLEX_ANNOTATIONS if (! rv) { + while (complexAnnotations_.size() < ComplexAnnotations::size_type(-key)) + complexAnnotations_.push_back(0); complexAnnotations_.replace(-key-1, new AnnotationRegistry::Entry()); rv = complexAnnotations_[-key-1].get(); } diff --git a/senf/Packets/PacketImpl.cti b/senf/Packets/PacketImpl.cti index 308e7b3..0627756 100644 --- a/senf/Packets/PacketImpl.cti +++ b/senf/Packets/PacketImpl.cti @@ -34,48 +34,37 @@ // senf::detail::AnnotationRegistry template -prefix_ key_t senf::detail::AnnotationRegistry::registerAnnotation() +prefix_ senf::detail::AnnotationRegistry::key_type +senf::detail::AnnotationRegistry::registerAnnotation() { - key_t key (simpleAnnotationCount_ >= SENF_PACKET_ANNOTATION_SLOTS + key_type key (simpleAnnotationCount_ >= SENF_PACKET_ANNOTATION_SLOTS || IsComplexAnnotation::value ? - ++complexAnnotationCount_ : simpleAnnotationCount_ ++); - registry_.insert(key, new Registration()); - std::cerr << ">> allocated key " << key - << " for " << prettyName(typeid(Annotation)) - << "(complex: " << IsComplexAnnotation::value - << ", convertible: " << boost::is_convertible::value - << ", size: " << sizeof(Annotation) - << ", max: " << SENF_PACKET_ANNOTATION_SLOTSIZE << ")" << std::endl; + std::pair reg ( + registry_.insert(key, new Registration())); + SENF_ASSERT(reg.second, "internal error: duplicate annotation key"); + index_.insert(std::make_pair(reg.first->second->v_name(), key)); return key; } template -prefix_ key_t senf::detail::AnnotationRegistry::lookup() +prefix_ senf::detail::AnnotationRegistry::key_type senf::detail::AnnotationRegistry::lookup() { - SENF_ASSERT( instance().keyBegin() <= AnnotationRegistry::Entry::key() - && AnnotationRegistry::Entry::key() < instance().keyEnd(), - "internal error: annotation key not registered" ); - SENF_ASSERT( AnnotationRegistry::Entry::key() < 0 - || ! IsComplexAnnotation::value, - "internal error: complex annotation registered with invalid key" ); - SENF_ASSERT( AnnotationRegistry::Entry::key() < SENF_PACKET_ANNOTATION_SLOTS, - "internal error: annotation key out of valid range" ); + SENF_ASSERT( + -instance().complexAnnotationCount_ <= AnnotationRegistry::Entry::key() + && AnnotationRegistry::Entry::key() < instance().simpleAnnotationCount_, + "internal error: annotation key not registered" ); + SENF_ASSERT( + AnnotationRegistry::Entry::key() < 0 + || ! IsComplexAnnotation::value, + "internal error: complex annotation registered with invalid key" ); + SENF_ASSERT( + AnnotationRegistry::Entry::key() < SENF_PACKET_ANNOTATION_SLOTS, + "internal error: annotation key out of valid range" ); return AnnotationRegistry::Entry::key(); } -prefix_ key_t senf::detail::AnnotationRegistry::keyBegin() - const -{ - return -complexAnnotationCount_; -} - -prefix_ key_t senf::detail::AnnotationRegistry::keyEnd() - const -{ - return simpleAnnotationCount_; -} - /////////////////////////////////////////////////////////////////////////// // senf::detail::PacketImpl @@ -102,7 +91,7 @@ prefix_ senf::detail::PacketImpl::PacketImpl(InputIterator first, InputIterator template prefix_ Annotation & senf::detail::PacketImpl::annotation() { - AnnotationRegistry::key_t key (AnnotationRegistry::lookup()); + AnnotationRegistry::key_type key (AnnotationRegistry::lookup()); void * antn (key >= 0 ? & simpleAnnotations_[key] : complexAnnotation()); SENF_ASSERT( antn, "internal error: null annotation pointer" ); return * static_cast(antn); diff --git a/senf/Packets/PacketImpl.hh b/senf/Packets/PacketImpl.hh index 3aa2964..fcdd71f 100644 --- a/senf/Packets/PacketImpl.hh +++ b/senf/Packets/PacketImpl.hh @@ -154,8 +154,8 @@ namespace detail { void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e); void updateIterators(PacketData * self, difference_type pos, difference_type n); - void * annotation(AnnotationRegistry::key_t key); // may return 0 ! - void * complexAnnotation(AnnotationRegistry::key_t key); // may return 0 ! + void * annotation(AnnotationRegistry::key_type key); // may return 0 ! + void * complexAnnotation(AnnotationRegistry::key_type key); // may return 0 ! template void * complexAnnotation(); diff --git a/senf/Packets/PacketImpl.ih b/senf/Packets/PacketImpl.ih index 06cb708..32ce82c 100644 --- a/senf/Packets/PacketImpl.ih +++ b/senf/Packets/PacketImpl.ih @@ -28,7 +28,10 @@ // Custom includes #include +#include #include +#include +#include #include #include #include @@ -61,38 +64,13 @@ namespace detail { : public senf::singleton { public: - typedef int key_t; - - using senf::singleton::instance; - - template class RegistrationProxy; - - class EntryBase; - template class Entry; - - template - key_t registerAnnotation(); - - void dump(key_t key, std::ostream & os, void * annotation) const; - std::string name(key_t key) const; - bool isComplex(key_t key) const; - unsigned size(key_t key) const; - - template - static key_t lookup(); - - key_t keyBegin() const; - key_t keyEnd() const; - - void dumpRegistrations(std::ostream & os); + typedef int key_type; private: - AnnotationRegistry(); - struct RegistrationBase { virtual ~RegistrationBase () {}; - key_t key; + key_type key; virtual void v_dump(std::ostream & os, void * annotation) const = 0; virtual std::string v_name() const = 0; virtual bool v_isComplex() const = 0; @@ -113,11 +91,49 @@ namespace detail { { return sizeof(Annotation); } }; - key_t simpleAnnotationCount_; - key_t complexAnnotationCount_; + typedef boost::ptr_map Registry; + // Index must be a multi-map since two identically named classes + // both in the anonymous namespace both have the same demangled name. + // we could sort on the mangled name instead ... + typedef std::multimap Index; + + public: + typedef boost::transform_iterator< ::__gnu_cxx::select2nd, + Index::const_iterator > iterator; + + using senf::singleton::instance; + + template class RegistrationProxy; + + class EntryBase; + template class Entry; + + template + key_type registerAnnotation(); + + void dump(key_type key, std::ostream & os, void * annotation) const; + std::string name(key_type key) const; + bool isComplex(key_type key) const; + unsigned size(key_type key) const; + + template + static key_type lookup(); + + iterator begin() const; + iterator end() const; + + void dumpRegistrations(std::ostream & os); + + private: + AnnotationRegistry(); + + key_type simpleAnnotationCount_; + key_type complexAnnotationCount_; - typedef boost::ptr_map Registry; Registry registry_; + // The index is needed to ensure a persistent and reproducible + // ordering of the annotations when dumping + Index index_; friend class senf::singleton; }; @@ -146,10 +162,10 @@ namespace detail { : public AnnotationRegistry::EntryBase { static RegistrationProxy proxy_; - static AnnotationRegistry::key_t key_; + static AnnotationRegistry::key_type key_; public: // We use this member to force instantiation of proxy_ ... - static AnnotationRegistry::key_t key() + static AnnotationRegistry::key_type key() { senf::IGNORE(&proxy_); return key_; } virtual void * get() { return & annotation_; } diff --git a/senf/Packets/PacketInterpreter.cc b/senf/Packets/PacketInterpreter.cc index 6fd279a..62b912c 100644 --- a/senf/Packets/PacketInterpreter.cc +++ b/senf/Packets/PacketInterpreter.cc @@ -75,8 +75,8 @@ prefix_ senf::PacketInterpreterBase::ptr senf::PacketInterpreterBase::append(ptr prefix_ void senf::PacketInterpreterBase::dump(std::ostream & os) { try { - if (detail::AnnotationRegistry::instance().keyBegin() - != detail::AnnotationRegistry::instance().keyEnd()) { + if (detail::AnnotationRegistry::instance().begin() + != detail::AnnotationRegistry::instance().end()) { os << "Annotations:\n"; impl().dumpAnnotations(os); }