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

Reply via email to