Commit 9bd0fcbe authored by Christian Stenger's avatar Christian Stenger

Revert "Clang: Improve locking of string cache"

This reverts commit be939a80.
'shared_timed_mutex' is not available before Xcode 9.

Change-Id: I1ac6c2b3691d5b4f457c431e255629a526c48c3a
Reviewed-by: Eike Ziller's avatarEike Ziller <eike.ziller@qt.io>
parent 07bec99e
...@@ -67,12 +67,12 @@ class FilePathCache final : private FilePathCacheBase ...@@ -67,12 +67,12 @@ class FilePathCache final : private FilePathCacheBase
{ {
using DirectoryPathCache = StringCache<Utils::PathString, using DirectoryPathCache = StringCache<Utils::PathString,
int, int,
std::shared_timed_mutex, std::mutex,
decltype(&Utils::reverseCompare), decltype(&Utils::reverseCompare),
Utils::reverseCompare>; Utils::reverseCompare>;
using FileNameCache = StringCache<Utils::SmallString, using FileNameCache = StringCache<Utils::SmallString,
int, int,
std::shared_timed_mutex, std::mutex,
decltype(&Utils::compare), decltype(&Utils::compare),
Utils::compare>; Utils::compare>;
public: public:
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include <utils/smallstringfwd.h> #include <utils/smallstringfwd.h>
#include <algorithm> #include <algorithm>
#include <shared_mutex> #include <mutex>
#include <vector> #include <vector>
namespace ClangBackEnd { namespace ClangBackEnd {
...@@ -54,8 +54,6 @@ public: ...@@ -54,8 +54,6 @@ public:
NonLockingMutex& operator=(const NonLockingMutex&) = delete; NonLockingMutex& operator=(const NonLockingMutex&) = delete;
void lock() {} void lock() {}
void unlock() {} void unlock() {}
void lock_shared() {}
void unlock_shared() {}
}; };
template <typename StringType, typename IndexType> template <typename StringType, typename IndexType>
...@@ -124,34 +122,23 @@ public: ...@@ -124,34 +122,23 @@ public:
IndexType stringId(Utils::SmallStringView stringView) IndexType stringId(Utils::SmallStringView stringView)
{ {
std::shared_lock<Mutex> sharedLock(m_mutex); std::lock_guard<Mutex> lock(m_mutex);
Found found = find(stringView);
if (found.wasFound)
return found.iterator->id;
sharedLock.unlock();
std::lock_guard<Mutex> exclusiveLock(m_mutex);
found = find(stringView); return ungardedStringId(stringView);
if (!found.wasFound) {
IndexType index = insertString(found.iterator, stringView, IndexType(m_indices.size()));
found.iterator = m_strings.begin() + index;;
}
return found.iterator->id;
} }
template <typename Container> template <typename Container>
std::vector<IndexType> stringIds(const Container &strings) std::vector<IndexType> stringIds(const Container &strings)
{ {
std::lock_guard<Mutex> lock(m_mutex);
std::vector<IndexType> ids; std::vector<IndexType> ids;
ids.reserve(strings.size()); ids.reserve(strings.size());
std::transform(strings.begin(), std::transform(strings.begin(),
strings.end(), strings.end(),
std::back_inserter(ids), std::back_inserter(ids),
[&] (const auto &string) { return this->stringId(string); }); [&] (const auto &string) { return this->ungardedStringId(string); });
return ids; return ids;
} }
...@@ -163,7 +150,7 @@ public: ...@@ -163,7 +150,7 @@ public:
StringType string(IndexType id) const StringType string(IndexType id) const
{ {
std::shared_lock<Mutex> sharedLock(m_mutex); std::lock_guard<Mutex> lock(m_mutex);
return m_strings.at(m_indices.at(id)).string; return m_strings.at(m_indices.at(id)).string;
} }
...@@ -171,25 +158,28 @@ public: ...@@ -171,25 +158,28 @@ public:
template<typename Function> template<typename Function>
StringType string(IndexType id, Function storageFunction) StringType string(IndexType id, Function storageFunction)
{ {
std::shared_lock<Mutex> sharedLock(m_mutex); std::lock_guard<Mutex> lock(m_mutex);
if (IndexType(m_indices.size()) > id && m_indices.at(id) >= 0)
return m_strings.at(m_indices.at(id)).string;
sharedLock.unlock();
std::lock_guard<Mutex> exclusiveLock(m_mutex);
IndexType index; IndexType index;
StringType string{storageFunction(id)}; if (IndexType(m_indices.size()) <= id) {
index = insertString(find(string).iterator, string, id); StringType string{storageFunction(id)};
index = insertString(find(string).iterator, string, id);
} else {
index = m_indices.at(id);
if (index < 0) {
StringType string{storageFunction(id)};
index = insertString(find(string).iterator, string, id);
}
}
return m_strings[index].string; return m_strings.at(index).string;
} }
std::vector<StringType> strings(const std::vector<IndexType> &ids) const std::vector<StringType> strings(const std::vector<IndexType> &ids) const
{ {
std::shared_lock<Mutex> sharedLock(m_mutex); std::lock_guard<Mutex> lock(m_mutex);
std::vector<StringType> strings; std::vector<StringType> strings;
strings.reserve(ids.size()); strings.reserve(ids.size());
...@@ -210,21 +200,12 @@ public: ...@@ -210,21 +200,12 @@ public:
template<typename Function> template<typename Function>
IndexType stringId(Utils::SmallStringView stringView, Function storageFunction) IndexType stringId(Utils::SmallStringView stringView, Function storageFunction)
{ {
std::shared_lock<Mutex> sharedLock(m_mutex); std::lock_guard<Mutex> lock(m_mutex);
Found found = find(stringView); Found found = find(stringView);
if (found.wasFound) if (!found.wasFound)
return found.iterator->id; insertString(found.iterator, stringView, storageFunction(stringView));
sharedLock.unlock();
std::lock_guard<Mutex> exclusiveLock(m_mutex);
found = find(stringView);
if (!found.wasFound) {
IndexType index = insertString(found.iterator, stringView, storageFunction(stringView));
found.iterator = m_strings.begin() + index;
}
return found.iterator->id; return found.iterator->id;
} }
...@@ -235,6 +216,16 @@ public: ...@@ -235,6 +216,16 @@ public:
} }
private: private:
IndexType ungardedStringId(Utils::SmallStringView stringView)
{
Found found = find(stringView);
if (!found.wasFound)
insertString(found.iterator, stringView, IndexType(m_indices.size()));
return found.iterator->id;
}
Found find(Utils::SmallStringView stringView) Found find(Utils::SmallStringView stringView)
{ {
return findInSorted(m_strings.cbegin(), m_strings.cend(), stringView, compare); return findInSorted(m_strings.cbegin(), m_strings.cend(), stringView, compare);
......
...@@ -34,6 +34,4 @@ public: ...@@ -34,6 +34,4 @@ public:
MOCK_METHOD0(lock, void ()); MOCK_METHOD0(lock, void ());
MOCK_METHOD0(unlock, void ()); MOCK_METHOD0(unlock, void ());
MOCK_METHOD0(lock_shared, void ());
MOCK_METHOD0(unlock_shared, void ());
}; };
...@@ -329,110 +329,48 @@ TEST_F(StringCache, FindInSortedFifeReverse) ...@@ -329,110 +329,48 @@ TEST_F(StringCache, FindInSortedFifeReverse)
ASSERT_TRUE(found.wasFound); ASSERT_TRUE(found.wasFound);
} }
TEST_F(StringCache, StringIdIsReadAndWriteLockedForUnknownEntry) TEST_F(StringCache, StringIdIsLocked)
{ {
InSequence s;
EXPECT_CALL(mockMutex, lock_shared());
EXPECT_CALL(mockMutex, unlock_shared());
EXPECT_CALL(mockMutex, lock()); EXPECT_CALL(mockMutex, lock());
EXPECT_CALL(mockMutex, unlock()); EXPECT_CALL(mockMutex, unlock());
cache.stringId("foo"); cache.stringId("foo");
} }
TEST_F(StringCache, StringIdWithStorageFunctionIsReadAndWriteLockedForUnknownEntry) TEST_F(StringCache, StringIdsIsLocked)
{ {
InSequence s;
EXPECT_CALL(mockMutex, lock_shared());
EXPECT_CALL(mockMutex, unlock_shared());
EXPECT_CALL(mockMutex, lock()); EXPECT_CALL(mockMutex, lock());
EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("foo")));
EXPECT_CALL(mockMutex, unlock()); EXPECT_CALL(mockMutex, unlock());
cache.stringId("foo", mockStorageFetchDirectyId);
}
TEST_F(StringCache, StringIdWithStorageFunctionIsReadLockedForKnownEntry)
{
InSequence s;
cache.stringId("foo", mockStorageFetchDirectyId);
EXPECT_CALL(mockMutex, lock_shared());
EXPECT_CALL(mockMutex, unlock_shared());
EXPECT_CALL(mockMutex, lock()).Times(0);
EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("foo"))).Times(0);
EXPECT_CALL(mockMutex, unlock()).Times(0);
cache.stringId("foo", mockStorageFetchDirectyId);
}
TEST_F(StringCache, StringIdIsReadLockedForKnownEntry)
{
cache.stringId("foo");
EXPECT_CALL(mockMutex, lock_shared());
EXPECT_CALL(mockMutex, unlock_shared());
EXPECT_CALL(mockMutex, lock()).Times(0);
EXPECT_CALL(mockMutex, unlock()).Times(0);
cache.stringId("foo");
}
TEST_F(StringCache, StringIdsIsLocked)
{
EXPECT_CALL(mockMutex, lock_shared());
EXPECT_CALL(mockMutex, unlock_shared());
cache.stringIds({"foo"}); cache.stringIds({"foo"});
} }
TEST_F(StringCache, StringIsLocked) TEST_F(StringCache, StringIsLocked)
{ {
auto id = cache.stringId("foo"); cache.stringId("foo");
EXPECT_CALL(mockMutex, lock_shared()); EXPECT_CALL(mockMutex, lock());
EXPECT_CALL(mockMutex, unlock_shared()); EXPECT_CALL(mockMutex, unlock());
cache.string(id); cache.string(0);
} }
TEST_F(StringCache, StringsIsLocked) TEST_F(StringCache, StringsIsLocked)
{ {
auto ids = cache.stringIds({"foo", "bar"}); cache.stringId("foo");
EXPECT_CALL(mockMutex, lock_shared());
EXPECT_CALL(mockMutex, unlock_shared());
cache.strings(ids);
}
TEST_F(StringCache, StringWithStorageFunctionIsReadAndWriteLockedForUnknownId)
{
InSequence s;
EXPECT_CALL(mockMutex, lock_shared());
EXPECT_CALL(mockMutex, unlock_shared());
EXPECT_CALL(mockMutex, lock()); EXPECT_CALL(mockMutex, lock());
EXPECT_CALL(mockStorage, fetchDirectoryPath(Eq(41)));
EXPECT_CALL(mockMutex, unlock()); EXPECT_CALL(mockMutex, unlock());
cache.string(41, mockStorageFetchDirectyPath); cache.strings({0});
} }
TEST_F(StringCache, StringWithStorageFunctionIsReadLockedForKnownId) TEST_F(StringCache, StringIdWithStorageFunctionIsLocked)
{ {
InSequence s; EXPECT_CALL(mockMutex, lock());
cache.string(41, mockStorageFetchDirectyPath); EXPECT_CALL(mockMutex, unlock());
EXPECT_CALL(mockMutex, lock_shared());
EXPECT_CALL(mockMutex, unlock_shared());
EXPECT_CALL(mockMutex, lock()).Times(0);
EXPECT_CALL(mockStorage, fetchDirectoryPath(Eq(41))).Times(0);
EXPECT_CALL(mockMutex, unlock()).Times(0);
cache.string(41, mockStorageFetchDirectyPath); cache.stringId("foo", mockStorageFetchDirectyId);
} }
TEST_F(StringCache, StringIdWithStorageFunctionWhichHasNoEntryIsCallingStorageFunction) TEST_F(StringCache, StringIdWithStorageFunctionWhichHasNoEntryIsCallingStorageFunction)
......
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