[Libreoffice-commits] core.git: Branch 'private/kohei/calc-shared-string' - 2 commits - include/svl svl/qa svl/source
Kohei Yoshida
kohei.yoshida at collabora.com
Wed Oct 2 13:34:29 PDT 2013
include/svl/stringpool.hxx | 24 +++++++++++++++-
svl/qa/unit/svl.cxx | 22 ++++++++++++++-
svl/source/misc/stringpool.cxx | 59 ++++++++++++++++++++++++++++++++++++++---
3 files changed, 99 insertions(+), 6 deletions(-)
New commits:
commit b82477525d3fc2ffa553534743b89fa6e5ec1b5a
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Oct 2 16:35:41 2013 -0400
Add purge() method to purge unreferenced strings from the pool.
But this code needs more work.
Change-Id: I538eebf5eb1738a2cfeebc22052b3d5db6001b6b
diff --git a/include/svl/stringpool.hxx b/include/svl/stringpool.hxx
index d2eca12..cac7637 100644
--- a/include/svl/stringpool.hxx
+++ b/include/svl/stringpool.hxx
@@ -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;
};
diff --git a/svl/qa/unit/svl.cxx b/svl/qa/unit/svl.cxx
index 58882bb..26cad83 100644
--- a/svl/qa/unit/svl.cxx
+++ b/svl/qa/unit/svl.cxx
@@ -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,
diff --git a/svl/source/misc/stringpool.cxx b/svl/source/misc/stringpool.cxx
index 11b6288..f4d9996 100644
--- a/svl/source/misc/stringpool.cxx
+++ b/svl/source/misc/stringpool.cxx
@@ -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);
commit dfcf3dc7dc6dd2acbb5b302c52429a30c0bc717a
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Oct 2 14:06:13 2013 -0400
The map actualy needs to store OUString to have it ref-counted automatically.
Change-Id: Iff6fcf3aba73f2d06ac0c885b39e69ac0febc49f
diff --git a/include/svl/stringpool.hxx b/include/svl/stringpool.hxx
index 4436efe..d2eca12 100644
--- a/include/svl/stringpool.hxx
+++ b/include/svl/stringpool.hxx
@@ -29,7 +29,7 @@ class SVL_DLLPUBLIC StringPool
{
typedef boost::unordered_set<OUString, OUStringHash> StrHashType;
typedef std::pair<StrHashType::iterator, bool> InsertResultType;
- typedef boost::unordered_map<const rtl_uString*, const rtl_uString*> StrIdMapType;
+ typedef boost::unordered_map<const rtl_uString*, OUString> StrIdMapType;
StrHashType maStrPool;
StrHashType maStrPoolUpper;
diff --git a/svl/source/misc/stringpool.cxx b/svl/source/misc/stringpool.cxx
index 76dc4aa..11b6288 100644
--- a/svl/source/misc/stringpool.cxx
+++ b/svl/source/misc/stringpool.cxx
@@ -40,8 +40,7 @@ rtl_uString* StringPool::intern( const OUString& rStr )
return pOrig;
// Set mapping.
- rtl_uString* pUpper = aRes.first->pData;
- maToUpperMap.insert(StrIdMapType::value_type(pOrig, pUpper));
+ maToUpperMap.insert(StrIdMapType::value_type(pOrig, *aRes.first));
return pOrig;
}
@@ -64,7 +63,7 @@ StringPool::StrIdType StringPool::getIdentifierIgnoreCase( const OUString& rStr
// Passed string is not in the pool.
return 0;
- const rtl_uString* pUpper = itUpper->second;
+ const rtl_uString* pUpper = itUpper->second.pData;
return reinterpret_cast<StrIdType>(pUpper);
}
More information about the Libreoffice-commits
mailing list