summaryrefslogtreecommitdiff
path: root/svl
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-11-18 22:32:36 -0500
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-11-18 22:33:20 -0500
commitbbc9992094cbab668593cd6d84659d4d1a48e44f (patch)
tree826c516c7b7e4bf43f8df0b369f3173c96bb794d /svl
parent764600bc6175a32d119487afda2e8409f3395666 (diff)
Apply pimpl to svl::SharedStringPool.
Change-Id: I351505f0c1cb25c47897e0cfffdb258f8e87081f
Diffstat (limited to 'svl')
-rw-r--r--svl/qa/unit/svl.cxx1
-rw-r--r--svl/source/misc/sharedstringpool.cxx126
2 files changed, 77 insertions, 50 deletions
diff --git a/svl/qa/unit/svl.cxx b/svl/qa/unit/svl.cxx
index 25bc217c8adb..dd856fb5125c 100644
--- a/svl/qa/unit/svl.cxx
+++ b/svl/qa/unit/svl.cxx
@@ -34,6 +34,7 @@
#include <svl/zforlist.hxx>
#include <svl/zformat.hxx>
#include <svl/sharedstringpool.hxx>
+#include <svl/sharedstring.hxx>
#include <unotools/syslocale.hxx>
#include <boost/scoped_ptr.hpp>
diff --git a/svl/source/misc/sharedstringpool.cxx b/svl/source/misc/sharedstringpool.cxx
index e78e0965832e..6d0e80083e6e 100644
--- a/svl/source/misc/sharedstringpool.cxx
+++ b/svl/source/misc/sharedstringpool.cxx
@@ -8,32 +8,86 @@
*/
#include <svl/sharedstringpool.hxx>
+#include <svl/sharedstring.hxx>
#include <unotools/charclass.hxx>
+#include <osl/mutex.hxx>
+
+#include <boost/unordered_map.hpp>
+#include <boost/unordered_set.hpp>
namespace svl {
-SharedStringPool::SharedStringPool( const CharClass* pCharClass ) : mpCharClass(pCharClass) {}
+namespace {
+
+inline sal_Int32 getRefCount( const rtl_uString* p )
+{
+ return (p->refCount & 0x3FFFFFFF);
+}
+
+typedef boost::unordered_set<OUString, OUStringHash> StrHashType;
+typedef std::pair<StrHashType::iterator, bool> InsertResultType;
+typedef boost::unordered_map<const rtl_uString*, OUString> StrStoreType;
+
+InsertResultType findOrInsert( StrHashType& rPool, const OUString& rStr )
+{
+ StrHashType::iterator it = rPool.find(rStr);
+ bool bInserted = false;
+ if (it == rPool.end())
+ {
+ // Not yet in the pool.
+ std::pair<StrHashType::iterator, bool> r = rPool.insert(rStr);
+ if (!r.second)
+ // Insertion failed.
+ return InsertResultType(rPool.end(), false);
+
+ it = r.first;
+ bInserted = true;
+ }
+
+ return InsertResultType(it, bInserted);
+}
+
+}
+
+struct SharedStringPool::Impl
+{
+ mutable osl::Mutex maMutex;
+ StrHashType maStrPool;
+ StrHashType maStrPoolUpper;
+ StrStoreType maStrStore;
+ const CharClass* mpCharClass;
+
+ Impl( const CharClass* pCharClass ) : mpCharClass(pCharClass) {}
+};
+
+SharedStringPool::SharedStringPool( const CharClass* pCharClass ) :
+ mpImpl(new Impl(pCharClass)) {}
+
+SharedStringPool::~SharedStringPool()
+{
+ delete mpImpl;
+}
SharedString SharedStringPool::intern( const OUString& rStr )
{
- osl::MutexGuard aGuard(&maMutex);
+ osl::MutexGuard aGuard(&mpImpl->maMutex);
- InsertResultType aRes = findOrInsert(maStrPool, rStr);
- if (aRes.first == maStrPool.end())
+ InsertResultType aRes = findOrInsert(mpImpl->maStrPool, rStr);
+ if (aRes.first == mpImpl->maStrPool.end())
// Insertion failed.
return SharedString();
rtl_uString* pOrig = aRes.first->pData;
- if (!mpCharClass)
+ if (!mpImpl->mpCharClass)
// We don't track case insensitive strings.
return SharedString(pOrig, NULL);
if (!aRes.second)
{
// No new string has been inserted. Return the existing string in the pool.
- StrStoreType::iterator it = maStrStore.find(pOrig);
- if (it == maStrStore.end())
+ StrStoreType::iterator it = mpImpl->maStrStore.find(pOrig);
+ if (it == mpImpl->maStrStore.end())
return SharedString();
rtl_uString* pUpper = it->second.pData;
@@ -42,32 +96,23 @@ SharedString SharedStringPool::intern( const OUString& rStr )
// This is a new string insertion. Establish mapping to upper-case variant.
- OUString aUpper = mpCharClass->uppercase(rStr);
- aRes = findOrInsert(maStrPoolUpper, aUpper);
- if (aRes.first == maStrPoolUpper.end())
+ OUString aUpper = mpImpl->mpCharClass->uppercase(rStr);
+ aRes = findOrInsert(mpImpl->maStrPoolUpper, aUpper);
+ if (aRes.first == mpImpl->maStrPoolUpper.end())
// Failed to insert or fetch upper-case variant. Should never happen.
return SharedString();
- maStrStore.insert(StrStoreType::value_type(pOrig, *aRes.first));
+ mpImpl->maStrStore.insert(StrStoreType::value_type(pOrig, *aRes.first));
return SharedString(pOrig, aRes.first->pData);
}
-namespace {
-
-inline sal_Int32 getRefCount( const rtl_uString* p )
-{
- return (p->refCount & 0x3FFFFFFF);
-}
-
-}
-
void SharedStringPool::purge()
{
- osl::MutexGuard aGuard(&maMutex);
+ osl::MutexGuard aGuard(&mpImpl->maMutex);
StrHashType aNewStrPool;
- StrHashType::iterator it = maStrPool.begin(), itEnd = maStrPool.end();
+ StrHashType::iterator it = mpImpl->maStrPool.begin(), itEnd = mpImpl->maStrPool.end();
for (; it != itEnd; ++it)
{
const rtl_uString* p = it->pData;
@@ -75,20 +120,20 @@ void SharedStringPool::purge()
{
// Remove it from the upper string map. This should unref the
// upper string linked to this original string.
- maStrStore.erase(p);
+ mpImpl->maStrStore.erase(p);
}
else
// Still referenced outside the pool. Keep it.
aNewStrPool.insert(*it);
}
- maStrPool.swap(aNewStrPool);
+ mpImpl->maStrPool.swap(aNewStrPool);
aNewStrPool.clear(); // for re-use.
// Purge the upper string pool as well.
- it = maStrPoolUpper.begin();
- itEnd = maStrPoolUpper.end();
+ it = mpImpl->maStrPoolUpper.begin();
+ itEnd = mpImpl->maStrPoolUpper.end();
for (; it != itEnd; ++it)
{
const rtl_uString* p = it->pData;
@@ -96,38 +141,19 @@ void SharedStringPool::purge()
aNewStrPool.insert(*it);
}
- maStrPoolUpper.swap(aNewStrPool);
+ mpImpl->maStrPoolUpper.swap(aNewStrPool);
}
size_t SharedStringPool::getCount() const
{
- osl::MutexGuard aGuard(&maMutex);
- return maStrPool.size();
+ osl::MutexGuard aGuard(&mpImpl->maMutex);
+ return mpImpl->maStrPool.size();
}
size_t SharedStringPool::getCountIgnoreCase() const
{
- osl::MutexGuard aGuard(&maMutex);
- return maStrPoolUpper.size();
-}
-
-SharedStringPool::InsertResultType SharedStringPool::findOrInsert( StrHashType& rPool, const OUString& rStr ) const
-{
- StrHashType::iterator it = rPool.find(rStr);
- bool bInserted = false;
- if (it == rPool.end())
- {
- // Not yet in the pool.
- std::pair<StrHashType::iterator, bool> r = rPool.insert(rStr);
- if (!r.second)
- // Insertion failed.
- return InsertResultType(rPool.end(), false);
-
- it = r.first;
- bInserted = true;
- }
-
- return InsertResultType(it, bInserted);
+ osl::MutexGuard aGuard(&mpImpl->maMutex);
+ return mpImpl->maStrPoolUpper.size();
}
}