diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-11-18 22:32:36 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-11-18 22:33:20 -0500 |
commit | bbc9992094cbab668593cd6d84659d4d1a48e44f (patch) | |
tree | 826c516c7b7e4bf43f8df0b369f3173c96bb794d /svl/source | |
parent | 764600bc6175a32d119487afda2e8409f3395666 (diff) |
Apply pimpl to svl::SharedStringPool.
Change-Id: I351505f0c1cb25c47897e0cfffdb258f8e87081f
Diffstat (limited to 'svl/source')
-rw-r--r-- | svl/source/misc/sharedstringpool.cxx | 126 |
1 files changed, 76 insertions, 50 deletions
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(); } } |