15#include <unordered_map>
16#include <unordered_set>
25 StringWithHash(OUString s)
27 , hashCode(s.hashCode())
31 bool operator==(StringWithHash
const& rhs)
const
33 if (hashCode != rhs.hashCode)
35 return str == rhs.str;
42template <>
struct hash<StringWithHash>
44 std::size_t
operator()(
const StringWithHash& k)
const {
return k.hashCode; }
52sal_Int32 getRefCount(
const rtl_uString* p) {
return (
p->refCount & 0x3FFFFFFF); }
61 std::unordered_map<StringWithHash, OUString>
maStrMap;
71 : mpImpl(new
Impl(rCharClass))
82 StringWithHash aStrWithHash(rStr);
83 std::scoped_lock<std::mutex> aGuard(
mpImpl->maMutex);
85 auto[mapIt, bInserted] =
mpImpl->maStrMap.emplace(aStrWithHash, rStr);
88 return SharedString(mapIt->first.str.pData, mapIt->second.pData);
91 OUString aUpper =
mpImpl->mrCharClass.uppercase(rStr);
94 return SharedString(mapIt->first.str.pData, mapIt->second.pData);
99 StringWithHash aUpperWithHash(aUpper);
100 auto mapIt2 =
mpImpl->maStrMap.find(aUpperWithHash);
101 if (mapIt2 !=
mpImpl->maStrMap.end())
104 mapIt->second = mapIt2->first.str;
105 return SharedString(mapIt->first.str.pData, mapIt->second.pData);
111 mapIt->second = aUpper;
112 mpImpl->maStrMap.emplace_hint(mapIt2, aUpperWithHash, aUpper);
118 std::scoped_lock<std::mutex> aGuard(
mpImpl->maMutex);
126 auto it =
mpImpl->maStrMap.begin();
127 auto itEnd =
mpImpl->maStrMap.end();
130 rtl_uString* p1 = it->first.str.pData;
131 rtl_uString* p2 = it->second.pData;
137 if (getRefCount(p1) == 1)
139 it =
mpImpl->maStrMap.erase(it);
146 it =
mpImpl->maStrMap.begin();
147 itEnd =
mpImpl->maStrMap.end();
150 rtl_uString* p1 = it->first.str.pData;
151 rtl_uString* p2 = it->second.pData;
157 if (getRefCount(p1) == 2)
159 it =
mpImpl->maStrMap.erase(it);
169 std::scoped_lock<std::mutex> aGuard(
mpImpl->maMutex);
170 return mpImpl->maStrMap.size();
175 std::scoped_lock<std::mutex> aGuard(
mpImpl->maMutex);
177 std::unordered_set<OUString> aUpperSet;
178 for (
auto const& pair :
mpImpl->maStrMap)
179 aUpperSet.insert(pair.second);
180 return aUpperSet.size();
void purge()
Go through all string objects in the pool, and clear those that are no longer used outside of the poo...
size_t getCountIgnoreCase() const
SharedString intern(const OUString &rStr)
Intern a string object into the shared string pool.
SharedStringPool(const SharedStringPool &)=delete
std::unique_ptr< Impl > mpImpl
static const OUString EMPTY_STRING
static const SharedString & getEmptyString()
std::size_t operator()(const StringWithHash &k) const
std::unordered_map< StringWithHash, OUString > maStrMap
const CharClass & mrCharClass
Impl(const CharClass &rCharClass)
constexpr bool operator==(TypedWhichId< T > const &lhs, TypedWhichId< T > rhs)