binaryurp/source/cache.hxx | 125 +++++++----------- binaryurp/source/lessoperators.cxx | 45 +++++- binaryurp/source/lessoperators.hxx | 4 bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx | 2 bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx | 2 configmgr/source/modifications.hxx | 7 - 6 files changed, 96 insertions(+), 89 deletions(-)
New commits: commit b220aecac531570269078b602c80e56d41d05c51 Author: Herbert Dürr <h...@apache.org> Date: Thu Dec 12 09:48:15 2013 +0000 #i122208# force boost *map for configmgr's Modifications Node structure The C++ standards allows that the instantiation of incomplete types fails. The Node structure had this problem because it contained a map of Node structures itself. Boost containers explicitly allow recursive types so they solve that. diff --git a/configmgr/source/modifications.hxx b/configmgr/source/modifications.hxx index f532af9..1aa0d24 100644 --- a/configmgr/source/modifications.hxx +++ b/configmgr/source/modifications.hxx @@ -26,20 +26,19 @@ #include "sal/config.h" -#include <map> +#include <boost/unordered_map.hpp> // using the boost container because it explicitly allows recursive types #include "boost/noncopyable.hpp" #include "path.hxx" - -namespace rtl { class OUString; } +#include "rtl/ustring.hxx" namespace configmgr { class Modifications: private boost::noncopyable { public: struct Node { - typedef std::map< rtl::OUString, Node > Children; + typedef boost::unordered_map< rtl::OUString, Node, rtl::OUStringHash > Children; Children children; }; commit b908fff1715f34373212c10f77244bf88574db10 Author: Herbert Dürr <h...@apache.org> Date: Thu Dec 12 09:23:56 2013 +0000 #i122195# fix leak when handling exceptions in the UNO bridge for OSX 64bit diff --git a/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx b/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx index 3ffaa4b..96a65fc 100644 --- a/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx +++ b/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx @@ -213,8 +213,6 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR static void deleteException( void * pExc ) { __cxa_exception const * header = ((__cxa_exception const *)pExc - 1); - if( !header->exceptionType) // TODO: remove this when getRTTI() always returns non-NULL - return; // NOTE: leak for now typelib_TypeDescription * pTD = 0; OUString unoName( toUNOname( header->exceptionType->name() ) ); ::typelib_typedescription_getByName( &pTD, unoName.pData ); diff --git a/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx b/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx index bcda4d6..279b275 100644 --- a/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx +++ b/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx @@ -40,7 +40,7 @@ struct _Unwind_Exception void * exception_cleanup; uintptr_t private_1; uintptr_t private_2; -} __attribute__((__aligned__)); +}; struct __cxa_exception { commit 8c1f2d28eb4ec226a37eac0f96dc079c9974771f Author: Herbert Dürr <h...@apache.org> Date: Thu Dec 12 08:50:55 2013 +0000 #i122208# replace the binaryurp cache for improved C++ compatibility The C++ standards allows that the instantiation of incomplete types fails. The Map::iterator in binaryurp Cache's Entry members had this problem. This rewrite makes the code work with all compliant C++ compilers/STLs such as clang/libc++. A Cache variant using an unordered_map is also provided and may be faster. An interesting alternative would be to use boost's multi_index_container. diff --git a/binaryurp/source/cache.hxx b/binaryurp/source/cache.hxx index 308edba..135a61d 100755 --- a/binaryurp/source/cache.hxx +++ b/binaryurp/source/cache.hxx @@ -27,7 +27,12 @@ #include "sal/config.h" #include <cstddef> -#include <map> +#include <list> +#ifdef USE_UNORDERED_MAP + #include <unordered_map> +#else + #include <map> +#endif #include "boost/noncopyable.hpp" #include "osl/diagnose.h" @@ -41,90 +46,66 @@ enum { size = 256, ignore = 0xFFFF }; } -template< typename T > class Cache: private boost::noncopyable { +template< typename T > class Cache : private boost::noncopyable { public: + typedef sal_uInt16 IdxType; + explicit Cache(std::size_t size): - size_(size), first_(map_.end()), last_(map_.end()) + size_(size) { OSL_ASSERT(size < cache::ignore); } - sal_uInt16 add(T const & content, bool * found) { - OSL_ASSERT(found != 0); - typename Map::iterator i(map_.find(content)); - *found = i != map_.end(); - if (i == map_.end()) { - typename Map::size_type n = map_.size(); - if (n < size_) { - i = - (map_.insert( - typename Map::value_type( - content, - Entry( - static_cast< sal_uInt16 >(n), map_.end(), - first_)))). - first; - if (first_ == map_.end()) { - last_ = i; - } else { - first_->second.prev = i; - } - first_ = i; - } else if (last_ != map_.end()) { - i = - (map_.insert( - typename Map::value_type( - content, - Entry(last_->second.index, map_.end(), first_)))). - first; - first_->second.prev = i; - first_ = i; - typename Map::iterator j(last_); - last_ = last_->second.prev; - last_->second.next = map_.end(); - map_.erase(j); - } else { - // Reached iff size_ == 0: - return cache::ignore; - } - } else if (i != first_) { - // Move to front (reached only if size_ > 1): - i->second.prev->second.next = i->second.next; - if (i->second.next == map_.end()) { - last_ = i->second.prev; - } else { - i->second.next->second.prev = i->second.prev; - } - i->second.prev = map_.end(); - i->second.next = first_; - first_->second.prev = i; - first_ = i; - } - return i->second.index; + IdxType add( const T& rContent, bool* pbFound) { + OSL_ASSERT( pbFound != NULL); + if( !size_) { + *pbFound = false; + return cache::ignore; + } + // try to insert into the map + list_.push_front( rContent); // create a temp entry + typedef std::pair<typename LruList::iterator, IdxType> MappedType; + typedef std::pair<typename LruItMap::iterator,bool> MapPair; + MapPair aMP = map_.insert( MappedType( list_.begin(), 0)); + *pbFound = !aMP.second; + + if( !aMP.second) { // insertion not needed => found the entry + list_.pop_front(); // remove the temp entry + list_.splice( list_.begin(), list_, aMP.first->first); // the found entry is moved to front + return aMP.first->second; } -private: - struct Entry; - - typedef std::map< T, Entry > Map; - - struct Entry { - sal_uInt16 index; - typename Map::iterator prev; - typename Map::iterator next; + // test insertion successful => it was new so we keep it + IdxType n = static_cast<IdxType>( map_.size() - 1); + if( n >= size_) { // cache full => replace the LRU entry + // find the least recently used element in the map + typename LruItMap::iterator it = map_.find( --list_.end()); + n = it->second; + map_.erase( it); // remove it from the map + list_.pop_back(); // remove from the list + } + aMP.first->second = n; + return n; + } - Entry( - sal_uInt16 theIndex, typename Map::iterator thePrev, - typename Map::iterator theNext): - index(theIndex), prev(thePrev), next(theNext) {} - }; +private: + typedef std::list<T> LruList; // last recently used list + typedef typename LruList::iterator LruListIt; +#ifdef URPCACHE_USES_UNORDERED_MAP + struct HashT{ size_t operator()( const LruListIt& rA) const { return hash(*rA;);}; + struct EqualT{ bool operator()( const LruListIt& rA, const LruListIt& rB) const { return *rA==*rB;}}; + typedef ::std::unordered_map< LruListIt, IdxType, HashT, EqualT > LruItMap; // a map into a LruList +#else + struct CmpT{ bool operator()( const LruListIt& rA, const LruListIt& rB) const { return (*rA<*rB);}}; + typedef ::std::map< LruListIt, IdxType, CmpT > LruItMap; // a map into a LruList +#endif std::size_t size_; - Map map_; - typename Map::iterator first_; - typename Map::iterator last_; + LruItMap map_; + LruList list_; }; } #endif + diff --git a/binaryurp/source/lessoperators.cxx b/binaryurp/source/lessoperators.cxx index 1f0aa00..b4fb149 100644 --- a/binaryurp/source/lessoperators.cxx +++ b/binaryurp/source/lessoperators.cxx @@ -36,14 +36,38 @@ namespace com { namespace sun { namespace star { namespace uno { -bool operator <(TypeDescription const & left, TypeDescription const & right) { - OSL_ASSERT(left.is() && right.is()); - typelib_TypeClass tc1 = left.get()->eTypeClass; - typelib_TypeClass tc2 = right.get()->eTypeClass; - return tc1 < tc2 || - (tc1 == tc2 && - (rtl::OUString(left.get()->pTypeName) < - rtl::OUString(right.get()->pTypeName))); +bool operator<( const TypeDescription& rLeft, const TypeDescription& rRight) { + OSL_ASSERT( rLeft.is() && rRight.is()); + const typelib_TypeDescription& rA = *rLeft.get(); + const typelib_TypeDescription& rB = *rRight.get(); + if( rA.eTypeClass != rA.eTypeClass) + return (rA.eTypeClass < rB.eTypeClass); + const sal_Int32 nCmp = rtl_ustr_compare_WithLength( + rA.pTypeName->buffer, rA.pTypeName->length, + rB.pTypeName->buffer, rB.pTypeName->length); + return (nCmp < 0); +} + +bool TypeDescEqual::operator()( const TypeDescription& rLeft, const TypeDescription& rRight) const +{ + OSL_ASSERT( rLeft.is() && rRight.is()); + const typelib_TypeDescription& rA = *rLeft.get(); + const typelib_TypeDescription& rB = *rRight.get(); + if( rA.eTypeClass != rB.eTypeClass) + return false; + const sal_Int32 nCmp = rtl_ustr_compare_WithLength( + rA.pTypeName->buffer, rA.pTypeName->length, + rB.pTypeName->buffer, rB.pTypeName->length); + return (nCmp == 0); +} + +sal_Int32 TypeDescHash::operator()( const TypeDescription& rTD) const +{ + OSL_ASSERT( rTD.is()); + const typelib_TypeDescription& rA = *rTD.get(); + sal_Int32 h = rtl_ustr_hashCode_WithLength( rA.pTypeName->buffer, rA.pTypeName->length); + h ^= static_cast<sal_Int32>(rA.eTypeClass); + return h; } } } } } @@ -51,8 +75,8 @@ bool operator <(TypeDescription const & left, TypeDescription const & right) { namespace rtl { bool operator <(ByteSequence const & left, ByteSequence const & right) { - for (sal_Int32 i = 0; i != std::min(left.getLength(), right.getLength()); - ++i) + const sal_Int32 nLen = std::min( left.getLength(), right.getLength()); + for( sal_Int32 i = 0; i < nLen; ++i ) { if (left[i] < right[i]) { return true; @@ -65,3 +89,4 @@ bool operator <(ByteSequence const & left, ByteSequence const & right) { } } + diff --git a/binaryurp/source/lessoperators.hxx b/binaryurp/source/lessoperators.hxx index 0e79325..c3b52e0 100644 --- a/binaryurp/source/lessoperators.hxx +++ b/binaryurp/source/lessoperators.hxx @@ -35,6 +35,10 @@ namespace com { namespace sun { namespace star { namespace uno { bool operator <(TypeDescription const & left, TypeDescription const & right); +struct TypeDescHash { sal_Int32 operator()( const TypeDescription&) const; }; + +struct TypeDescEqual { bool operator()( const TypeDescription&, const TypeDescription&) const; }; + } } } } namespace rtl {
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits