QmlDesigner: Improve storage handling in StorageCache

Using an explicit class for the storage not even makes the code easier
to understand but enables the possibility of code optimizations too.

Change-Id: I9239919d3385ba1bf141c23bdc3013b6c1e624ed
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2021-04-27 09:48:01 +02:00
parent 865fe1c2d0
commit 3862f67b8d
3 changed files with 24 additions and 29 deletions

View File

@@ -63,16 +63,14 @@ public:
template<typename Type, template<typename Type,
typename ViewType, typename ViewType,
typename IndexType, typename IndexType,
typename Storage,
typename Mutex, typename Mutex,
typename Compare, typename Compare,
Compare compare = Utils::compare, Compare compare = Utils::compare,
typename CacheEntry = StorageCacheEntry<Type, ViewType, IndexType>, typename CacheEntry = StorageCacheEntry<Type, ViewType, IndexType>>
typename FetchValue = std::function<Type(IndexType)>,
typename FetchId = std::function<IndexType(ViewType)>>
class StorageCache class StorageCache
{ {
template<typename T, typename V, typename I, typename M, typename C, C c, typename CE, typename, typename> friend StorageCache;
friend class StorageCache;
using ResultType = std::conditional_t<std::is_base_of<NonLockingMutex, Mutex>::value, ViewType, Type>; using ResultType = std::conditional_t<std::is_base_of<NonLockingMutex, Mutex>::value, ViewType, Type>;
@@ -82,9 +80,8 @@ public:
using const_iterator = typename CacheEntries::const_iterator; using const_iterator = typename CacheEntries::const_iterator;
using Found = QmlDesigner::Found<const_iterator>; using Found = QmlDesigner::Found<const_iterator>;
StorageCache(FetchValue fetchValue, FetchId fetchId, std::size_t reserveSize = 1024) StorageCache(Storage storage, std::size_t reserveSize = 1024)
: m_fetchValue{std::move(fetchValue)} : m_storage{std::move(storage)}
, m_fetchId{std::move(fetchId)}
{ {
m_entries.reserve(reserveSize); m_entries.reserve(reserveSize);
m_indices.reserve(reserveSize); m_indices.reserve(reserveSize);
@@ -165,7 +162,7 @@ public:
m_entries.begin(), m_entries.begin(),
m_entries.end(), m_entries.end(),
Utils::make_iterator([&](ViewType newView) { Utils::make_iterator([&](ViewType newView) {
IndexType index = m_fetchId(newView); IndexType index = m_storage.fetchId(newView);
newCacheEntries.emplace_back(newView, index); newCacheEntries.emplace_back(newView, index);
}), }),
less); less);
@@ -213,7 +210,7 @@ public:
if (!std::is_base_of<NonLockingMutex, Mutex>::value) if (!std::is_base_of<NonLockingMutex, Mutex>::value)
found = find(view); found = find(view);
if (!found.wasFound) { if (!found.wasFound) {
IndexType index = insertEntry(found.iterator, view, m_fetchId(view)); IndexType index = insertEntry(found.iterator, view, m_storage.fetchId(view));
found.iterator = m_entries.begin() + index; found.iterator = m_entries.begin() + index;
} }
@@ -249,7 +246,7 @@ public:
std::lock_guard<Mutex> exclusiveLock(m_mutex); std::lock_guard<Mutex> exclusiveLock(m_mutex);
IndexType index; IndexType index;
Type value{m_fetchValue(id)}; Type value{m_storage.fetchValue(id)};
index = insertEntry(find(value).iterator, value, id); index = insertEntry(find(value).iterator, value, id);
return std::move(m_entries[index].value); return std::move(m_entries[index].value);
@@ -330,8 +327,7 @@ private:
CacheEntries m_entries; CacheEntries m_entries;
std::vector<IndexType> m_indices; std::vector<IndexType> m_indices;
mutable Mutex m_mutex; mutable Mutex m_mutex;
FetchValue m_fetchValue; Storage m_storage;
FetchId m_fetchId;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -31,14 +31,6 @@ namespace QmlDesigner {
class NonLockingMutex; class NonLockingMutex;
template<typename Type, template<typename Type, typename ViewType, typename IndexType, typename Storage, typename Mutex, typename Compare, Compare compare, typename CacheEntry>
typename ViewType,
typename IndexType,
typename Mutex,
typename Compare,
Compare compare,
typename CacheEntry,
typename FetchValue,
typename FetchId>
class StorageCache; class StorageCache;
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -42,12 +42,21 @@ using uint64 = unsigned long long;
using QmlDesigner::findInSorted; using QmlDesigner::findInSorted;
using Utils::compare; using Utils::compare;
using Utils::reverseCompare; using Utils::reverseCompare;
using StorageIdFunction = std::function<int(Utils::SmallStringView)>;
using StorageStringFunction = std::function<Utils::PathString(int)>; class StorageAdapter
{
public:
auto fetchId(Utils::SmallStringView view) { return storage.fetchDirectoryId(view); }
auto fetchValue(int id) { return storage.fetchDirectoryPath(id); }
MockFilePathStorage &storage;
};
using CacheWithMockLocking = QmlDesigner::StorageCache<Utils::PathString, using CacheWithMockLocking = QmlDesigner::StorageCache<Utils::PathString,
Utils::SmallStringView, Utils::SmallStringView,
int, int,
StorageAdapter,
NiceMock<MockMutex>, NiceMock<MockMutex>,
decltype(&Utils::reverseCompare), decltype(&Utils::reverseCompare),
Utils::reverseCompare>; Utils::reverseCompare>;
@@ -55,6 +64,7 @@ using CacheWithMockLocking = QmlDesigner::StorageCache<Utils::PathString,
using CacheWithoutLocking = QmlDesigner::StorageCache<Utils::PathString, using CacheWithoutLocking = QmlDesigner::StorageCache<Utils::PathString,
Utils::SmallStringView, Utils::SmallStringView,
int, int,
StorageAdapter,
NiceMock<MockMutexNonLocking>, NiceMock<MockMutexNonLocking>,
decltype(&Utils::reverseCompare), decltype(&Utils::reverseCompare),
Utils::reverseCompare>; Utils::reverseCompare>;
@@ -87,11 +97,8 @@ protected:
protected: protected:
NiceMock<SqliteDatabaseMock> databaseMock; NiceMock<SqliteDatabaseMock> databaseMock;
NiceMock<MockFilePathStorage> mockStorage{databaseMock}; NiceMock<MockFilePathStorage> mockStorage{databaseMock};
StorageIdFunction mockStorageFetchDirectyId{ StorageAdapter storageAdapter{mockStorage};
[&](Utils::SmallStringView string) { return mockStorage.fetchDirectoryId(string); }}; Cache cache{storageAdapter};
StorageStringFunction mockStorageFetchDirectyPath{
[&](int id) { return mockStorage.fetchDirectoryPath(id); }};
Cache cache{mockStorageFetchDirectyPath, mockStorageFetchDirectyId};
typename Cache::MutexType &mockMutex = cache.mutex(); typename Cache::MutexType &mockMutex = cache.mutex();
Utils::PathString filePath1{"/file/pathOne"}; Utils::PathString filePath1{"/file/pathOne"};
Utils::PathString filePath2{"/file/pathTwo"}; Utils::PathString filePath2{"/file/pathTwo"};