[Libreoffice-commits] core.git: Branch 'aoo/trunk' - 3 commits - binaryurp/source bridges/source configmgr/source
Herbert Dürr
hdu at apache.org
Thu Dec 12 02:07:42 PST 2013
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 <hdu at 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 <hdu at 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 <hdu at 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 {
More information about the Libreoffice-commits
mailing list