summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svl/sharedstringpool.hxx27
-rw-r--r--svl/qa/unit/svl.cxx1
-rw-r--r--svl/source/misc/sharedstringpool.cxx126
3 files changed, 87 insertions, 67 deletions
diff --git a/include/svl/sharedstringpool.hxx b/include/svl/sharedstringpool.hxx
index e926f296bb50..16841f9491ec 100644
--- a/include/svl/sharedstringpool.hxx
+++ b/include/svl/sharedstringpool.hxx
@@ -10,16 +10,15 @@
#ifndef INCLUDED_SVL_SHAREDSTRINGPOOL_HXX
#define INCLUDED_SVL_SHAREDSTRINGPOOL_HXX
-#include <svl/sharedstring.hxx>
-#include <osl/mutex.hxx>
-
-#include <boost/unordered_map.hpp>
-#include <boost/unordered_set.hpp>
+#include <svl/svldllapi.h>
+#include <rtl/ustring.hxx>
class CharClass;
namespace svl {
+class SharedString;
+
/**
* Storage for pool of shared strings. It also provides mapping from
* original-cased strings to upper-cased strings for case insensitive
@@ -27,19 +26,16 @@ namespace svl {
*/
class SVL_DLLPUBLIC SharedStringPool
{
- typedef boost::unordered_set<OUString, OUStringHash> StrHashType;
- typedef std::pair<StrHashType::iterator, bool> InsertResultType;
- typedef boost::unordered_map<const rtl_uString*, OUString> StrStoreType;
+ struct Impl;
+ Impl* mpImpl;
- mutable osl::Mutex maMutex;
- StrHashType maStrPool;
- StrHashType maStrPoolUpper;
- StrStoreType maStrStore;
- const CharClass* mpCharClass;
+ SharedStringPool(); // disabled
+ SharedStringPool( const SharedStringPool& ); // disabled
+ SharedStringPool& operator=( const SharedStringPool& ); // disabled
public:
-
SharedStringPool( const CharClass* pCharClass );
+ ~SharedStringPool();
/**
* Intern a string object into the shared string pool.
@@ -60,9 +56,6 @@ public:
size_t getCount() const;
size_t getCountIgnoreCase() const;
-
-private:
- InsertResultType findOrInsert( StrHashType& rPool, const OUString& rStr ) const;
};
}
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();
}
}