Kaydet (Commit) 5f5876e5 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Add purge() method to purge unreferenced strings from the pool.

But this code needs more work.

Change-Id: I538eebf5eb1738a2cfeebc22052b3d5db6001b6b
üst 46ca6ab1
......@@ -54,7 +54,8 @@ public:
/**
* Get a unique ID of string object that's expected to be in the shared
* string pool. If the string is not in the pool, NULL is returned.
* string pool. If the string is not in the pool, NULL is returned. The
* ID obtained by this method can be used for case sensitive comparison.
*
* @param rStr string object to get the ID of.
*
......@@ -62,8 +63,27 @@ public:
*/
StrIdType getIdentifier( const OUString& rStr ) const;
/**
* Get a unique ID of string object for case insensitive comparison. The
* string object is expected to be in the pool.
*
* @param rStr string object to get the ID of.
*
* @return unique ID of the string object usable for case insensitive
* comparison.
*/
StrIdType getIdentifierIgnoreCase( const OUString& rStr ) const;
/**
* Go through all string objects in the pool, and clear those that are no
* longer used outside of the pool.
*/
void purge();
size_t getCount() const;
size_t getCountIgnoreCase() const;
private:
InsertResultType findOrInsert( StrHashType& rPool, const OUString& rStr ) const;
};
......
......@@ -36,7 +36,7 @@
#include "svl/stringpool.hxx"
#include "unotools/syslocale.hxx"
#define DEBUG_UNIT_TEST 0
#define DEBUG_UNIT_TEST 1
#if DEBUG_UNIT_TEST
#include <iostream>
......@@ -68,12 +68,14 @@ public:
void testNumberFormat();
void testStringPool();
void testStringPoolPurge();
void testFdo60915();
void testI116701();
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testNumberFormat);
CPPUNIT_TEST(testStringPool);
// CPPUNIT_TEST(testStringPoolPurge); // FIXME: String pool's life cycle needs more work.
CPPUNIT_TEST(testFdo60915);
CPPUNIT_TEST(testI116701);
CPPUNIT_TEST_SUITE_END();
......@@ -335,6 +337,24 @@ void Test::testStringPool()
CPPUNIT_ASSERT_EQUAL(si1, si2);
}
void Test::testStringPoolPurge()
{
SvtSysLocale aSysLocale;
svl::StringPool aPool(aSysLocale.GetCharClassPtr());
aPool.intern("Andy");
aPool.intern("andy");
aPool.intern("ANDY");
CPPUNIT_ASSERT_MESSAGE("Wrong string count.", aPool.getCount() == 3);
CPPUNIT_ASSERT_MESSAGE("Wrong case insensitive string count.", aPool.getCountIgnoreCase() == 1);
// Since no string objects referencing the pooled strings exist, purging
// the pool should empty it.
aPool.purge();
CPPUNIT_ASSERT_MESSAGE("Wrong string count.", aPool.getCount() == 0);
CPPUNIT_ASSERT_MESSAGE("Wrong case insensitive string count.", aPool.getCountIgnoreCase() == 0);
}
void Test::checkPreviewString(SvNumberFormatter& aFormatter,
const OUString& sCode,
double fPreviewNumber,
......
......@@ -67,6 +67,60 @@ StringPool::StrIdType StringPool::getIdentifierIgnoreCase( const OUString& rStr
return reinterpret_cast<StrIdType>(pUpper);
}
namespace {
inline sal_Int32 getRefCount( const rtl_uString* p )
{
return (p->refCount & 0x3FFFFFFF);
}
}
void StringPool::purge()
{
StrHashType aNewStrPool;
StrHashType::iterator it = maStrPool.begin(), itEnd = maStrPool.end();
for (; it != itEnd; ++it)
{
const rtl_uString* p = it->pData;
if (getRefCount(p) == 1)
{
// Remove it from the upper string map. This should unref the
// upper string linked to this original string.
maToUpperMap.erase(p);
}
else
// Still referenced outside the pool. Keep it.
aNewStrPool.insert(*it);
}
maStrPool.swap(aNewStrPool);
aNewStrPool.clear(); // for re-use.
// Purge the upper string pool as well.
it = maStrPoolUpper.begin();
itEnd = maStrPoolUpper.end();
for (; it != itEnd; ++it)
{
const rtl_uString* p = it->pData;
if (getRefCount(p) > 1)
aNewStrPool.insert(*it);
}
maStrPoolUpper.swap(aNewStrPool);
}
size_t StringPool::getCount() const
{
return maStrPool.size();
}
size_t StringPool::getCountIgnoreCase() const
{
return maStrPoolUpper.size();
}
StringPool::InsertResultType StringPool::findOrInsert( StrHashType& rPool, const OUString& rStr ) const
{
StrHashType::iterator it = rPool.find(rStr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment