svl/source/misc/sharedstringpool.cxx |   52 ++++++++++++++++++++++++++++-------
 1 file changed, 42 insertions(+), 10 deletions(-)

New commits:
commit b2ebceeaf49aa45979486997e6358697b7045361
Author:     Noel Grandin <n...@peralex.com>
AuthorDate: Tue Jan 26 20:29:23 2021 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Wed Jan 27 07:38:13 2021 +0100

    tdf#92456 store hash with string
    
    so it does not need re-computing when comparing keys.
    shave 5% off time for this bug.
    
    Change-Id: I48870567be00f0ea98cad69e9c48222cd64decf2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109992
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/svl/source/misc/sharedstringpool.cxx 
b/svl/source/misc/sharedstringpool.cxx
index 9ddb64fff88b..997648fac363 100644
--- a/svl/source/misc/sharedstringpool.cxx
+++ b/svl/source/misc/sharedstringpool.cxx
@@ -15,6 +15,36 @@
 #include <unordered_map>
 #include <unordered_set>
 
+/** create a key class that caches the hashcode */
+namespace
+{
+struct StringWithHash
+{
+    OUString str;
+    sal_Int32 hashCode;
+    StringWithHash(OUString s)
+        : str(s)
+        , hashCode(s.hashCode())
+    {
+    }
+
+    bool operator==(StringWithHash const& rhs) const
+    {
+        if (hashCode != rhs.hashCode)
+            return false;
+        return str == rhs.str;
+    }
+};
+}
+
+namespace std
+{
+template <> struct hash<StringWithHash>
+{
+    std::size_t operator()(const StringWithHash& k) const { return k.hashCode; 
}
+};
+}
+
 namespace svl
 {
 namespace
@@ -28,7 +58,7 @@ struct SharedStringPool::Impl
     // We use this map for two purposes - to store lower->upper case mappings
     // and to retrieve a shared uppercase object, so the management logic
     // is quite complex.
-    std::unordered_map<OUString, OUString> maStrMap;
+    std::unordered_map<StringWithHash, OUString> maStrMap;
     const CharClass& mrCharClass;
 
     explicit Impl(const CharClass& rCharClass)
@@ -46,35 +76,37 @@ SharedStringPool::~SharedStringPool() {}
 
 SharedString SharedStringPool::intern(const OUString& rStr)
 {
+    StringWithHash aStrWithHash(rStr);
     osl::MutexGuard aGuard(&mpImpl->maMutex);
 
-    auto[mapIt, bInserted] = mpImpl->maStrMap.emplace(rStr, rStr);
+    auto[mapIt, bInserted] = mpImpl->maStrMap.emplace(aStrWithHash, rStr);
     if (!bInserted)
         // there is already a mapping
-        return SharedString(mapIt->first.pData, mapIt->second.pData);
+        return SharedString(mapIt->first.str.pData, mapIt->second.pData);
 
     // This is a new string insertion. Establish mapping to upper-case variant.
     OUString aUpper = mpImpl->mrCharClass.uppercase(rStr);
     if (aUpper == rStr)
         // no need to do anything more, because we inserted an upper->upper 
mapping
-        return SharedString(mapIt->first.pData, mapIt->second.pData);
+        return SharedString(mapIt->first.str.pData, mapIt->second.pData);
 
     // We need to insert a lower->upper mapping, so also insert
     // an upper->upper mapping, which we can use both for when an upper string
     // is interned, and to look up a shared upper string.
-    auto mapIt2 = mpImpl->maStrMap.find(aUpper);
+    StringWithHash aUpperWithHash(aUpper);
+    auto mapIt2 = mpImpl->maStrMap.find(aUpperWithHash);
     if (mapIt2 != mpImpl->maStrMap.end())
     {
         // there is an already existing upper string
-        mapIt->second = mapIt2->first;
-        return SharedString(mapIt->first.pData, mapIt->second.pData);
+        mapIt->second = mapIt2->first.str;
+        return SharedString(mapIt->first.str.pData, mapIt->second.pData);
     }
 
     // There is no already existing upper string.
     // First, update using the iterator, can't do this later because
     // the iterator will be invalid.
     mapIt->second = aUpper;
-    mpImpl->maStrMap.emplace_hint(mapIt2, aUpper, aUpper);
+    mpImpl->maStrMap.emplace_hint(mapIt2, aUpperWithHash, aUpper);
     return SharedString(rStr.pData, aUpper.pData);
 }
 
@@ -92,7 +124,7 @@ void SharedStringPool::purge()
     auto itEnd = mpImpl->maStrMap.end();
     while (it != itEnd)
     {
-        rtl_uString* p1 = it->first.pData;
+        rtl_uString* p1 = it->first.str.pData;
         rtl_uString* p2 = it->second.pData;
         if (p1 != p2)
         {
@@ -112,7 +144,7 @@ void SharedStringPool::purge()
     itEnd = mpImpl->maStrMap.end();
     while (it != itEnd)
     {
-        rtl_uString* p1 = it->first.pData;
+        rtl_uString* p1 = it->first.str.pData;
         rtl_uString* p2 = it->second.pData;
         if (p1 == p2)
         {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to