forked from qt-creator/qt-creator
QmlDesigner: Modernize project storage watcher and file status cache
Change-Id: Ia46d87803a74ebec7b7cc078115dd0bbbd02ec4d Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -24,9 +24,7 @@ public:
|
||||
|
||||
void addSourceContextId(SourceContextId sourceContextId)
|
||||
{
|
||||
auto found = std::lower_bound(m_sourceContextIds.begin(),
|
||||
m_sourceContextIds.end(),
|
||||
sourceContextId);
|
||||
auto found = std::ranges::lower_bound(m_sourceContextIds, sourceContextId);
|
||||
|
||||
if (found == m_sourceContextIds.end() || *found != sourceContextId)
|
||||
m_sourceContextIds.insert(found, sourceContextId);
|
||||
|
@@ -25,24 +25,9 @@ public:
|
||||
&& first.lastModified == second.lastModified;
|
||||
}
|
||||
|
||||
friend bool operator!=(const FileStatus &first, const FileStatus &second)
|
||||
friend auto operator<=>(const FileStatus &first, const FileStatus &second)
|
||||
{
|
||||
return !(first == second);
|
||||
}
|
||||
|
||||
friend bool operator<(const FileStatus &first, const FileStatus &second)
|
||||
{
|
||||
return first.sourceId < second.sourceId;
|
||||
}
|
||||
|
||||
friend bool operator<(SourceId first, const FileStatus &second)
|
||||
{
|
||||
return first < second.sourceId;
|
||||
}
|
||||
|
||||
friend bool operator<(const FileStatus &first, SourceId second)
|
||||
{
|
||||
return first.sourceId < second;
|
||||
return first.sourceId <=> second.sourceId;
|
||||
}
|
||||
|
||||
bool isExisting() const { return sourceId && size >= 0 && lastModified >= 0; }
|
||||
|
@@ -24,12 +24,7 @@ long long FileStatusCache::fileSize(SourceId sourceId) const
|
||||
|
||||
void FileStatusCache::update(SourceId sourceId)
|
||||
{
|
||||
auto found = std::lower_bound(m_cacheEntries.begin(),
|
||||
m_cacheEntries.end(),
|
||||
sourceId,
|
||||
[](const auto &first, const auto &second) {
|
||||
return first < second;
|
||||
});
|
||||
auto found = std::ranges::lower_bound(m_cacheEntries, sourceId, {}, &FileStatus::sourceId);
|
||||
|
||||
if (found != m_cacheEntries.end() && found->sourceId == sourceId)
|
||||
*found = m_fileSystem.fileStatus(sourceId);
|
||||
@@ -37,13 +32,12 @@ void FileStatusCache::update(SourceId sourceId)
|
||||
|
||||
void FileStatusCache::update(SourceIds sourceIds)
|
||||
{
|
||||
std::set_intersection(m_cacheEntries.begin(),
|
||||
m_cacheEntries.end(),
|
||||
sourceIds.begin(),
|
||||
sourceIds.end(),
|
||||
Utils::make_iterator([&](auto &entry) {
|
||||
entry = m_fileSystem.fileStatus(entry.sourceId);
|
||||
}));
|
||||
Utils::set_greedy_intersection(
|
||||
m_cacheEntries,
|
||||
sourceIds,
|
||||
[&](auto &entry) { entry = m_fileSystem.fileStatus(entry.sourceId); },
|
||||
{},
|
||||
&FileStatus::sourceId);
|
||||
}
|
||||
|
||||
SourceIds FileStatusCache::modified(SourceIds sourceIds) const
|
||||
@@ -51,44 +45,43 @@ SourceIds FileStatusCache::modified(SourceIds sourceIds) const
|
||||
SourceIds modifiedSourceIds;
|
||||
modifiedSourceIds.reserve(sourceIds.size());
|
||||
|
||||
std::set_intersection(m_cacheEntries.begin(),
|
||||
m_cacheEntries.end(),
|
||||
sourceIds.begin(),
|
||||
sourceIds.end(),
|
||||
Utils::make_iterator([&](auto &entry) {
|
||||
Utils::set_greedy_intersection(
|
||||
m_cacheEntries,
|
||||
sourceIds,
|
||||
[&](auto &entry) {
|
||||
auto fileStatus = m_fileSystem.fileStatus(entry.sourceId);
|
||||
if (fileStatus != entry) {
|
||||
modifiedSourceIds.push_back(entry.sourceId);
|
||||
entry = fileStatus;
|
||||
}
|
||||
}));
|
||||
},
|
||||
{},
|
||||
&FileStatus::sourceId);
|
||||
|
||||
FileStatuses newEntries;
|
||||
newEntries.reserve(sourceIds.size());
|
||||
|
||||
std::set_difference(sourceIds.begin(),
|
||||
sourceIds.end(),
|
||||
m_cacheEntries.begin(),
|
||||
m_cacheEntries.end(),
|
||||
Utils::make_iterator([&](SourceId newSourceId) {
|
||||
Utils::set_greedy_difference(
|
||||
sourceIds,
|
||||
m_cacheEntries,
|
||||
[&](SourceId newSourceId) {
|
||||
newEntries.push_back(m_fileSystem.fileStatus(newSourceId));
|
||||
modifiedSourceIds.push_back(newSourceId);
|
||||
}));
|
||||
},
|
||||
{},
|
||||
{},
|
||||
&FileStatus::sourceId);
|
||||
|
||||
if (newEntries.size()) {
|
||||
FileStatuses mergedEntries;
|
||||
mergedEntries.reserve(m_cacheEntries.size() + newEntries.size());
|
||||
|
||||
std::set_union(newEntries.begin(),
|
||||
newEntries.end(),
|
||||
m_cacheEntries.begin(),
|
||||
m_cacheEntries.end(),
|
||||
std::back_inserter(mergedEntries));
|
||||
std::ranges::set_union(newEntries, m_cacheEntries, std::back_inserter(mergedEntries));
|
||||
|
||||
m_cacheEntries = std::move(mergedEntries);
|
||||
}
|
||||
|
||||
std::sort(modifiedSourceIds.begin(), modifiedSourceIds.end());
|
||||
std::ranges::sort(modifiedSourceIds);
|
||||
|
||||
return modifiedSourceIds;
|
||||
}
|
||||
@@ -100,12 +93,7 @@ FileStatusCache::size_type FileStatusCache::size() const
|
||||
|
||||
const FileStatus &FileStatusCache::find(SourceId sourceId) const
|
||||
{
|
||||
auto found = std::lower_bound(m_cacheEntries.begin(),
|
||||
m_cacheEntries.end(),
|
||||
sourceId,
|
||||
[](const auto &first, const auto &second) {
|
||||
return first < second;
|
||||
});
|
||||
auto found = std::ranges::lower_bound(m_cacheEntries, sourceId, {}, &FileStatus::sourceId);
|
||||
|
||||
if (found != m_cacheEntries.end() && found->sourceId == sourceId)
|
||||
return *found;
|
||||
|
@@ -13,27 +13,12 @@
|
||||
#include <sourcepathstorage/storagecache.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/set_algorithm.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
template<class InputIt1, class InputIt2, class Callable>
|
||||
void set_greedy_intersection_call(
|
||||
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable callable)
|
||||
{
|
||||
while (first1 != last1 && first2 != last2) {
|
||||
if (*first1 < *first2) {
|
||||
++first1;
|
||||
} else {
|
||||
if (*first2 < *first1)
|
||||
++first2;
|
||||
else
|
||||
callable(*first1++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FileSystemWatcher, typename Timer, class SourcePathCache>
|
||||
class ProjectStoragePathWatcher : public ProjectStoragePathWatcherInterface,
|
||||
public ProjectStorageTriggerUpdateInterface
|
||||
@@ -63,7 +48,7 @@ public:
|
||||
addEntries(entires);
|
||||
|
||||
auto notContainsdId = [&, &ids = ids](WatcherEntry entry) {
|
||||
return !std::binary_search(ids.begin(), ids.end(), entry.id);
|
||||
return !std::ranges::binary_search(ids, entry.id);
|
||||
};
|
||||
removeUnusedEntries(entires, notContainsdId);
|
||||
}
|
||||
@@ -76,10 +61,8 @@ public:
|
||||
addEntries(entires);
|
||||
|
||||
auto notContainsId = [&, &ids = ids](WatcherEntry entry) {
|
||||
return !std::binary_search(ids.begin(), ids.end(), entry.id)
|
||||
|| !std::binary_search(sourceContextIds.begin(),
|
||||
sourceContextIds.end(),
|
||||
entry.sourceContextId);
|
||||
return !std::ranges::binary_search(ids, entry.id)
|
||||
|| !std::ranges::binary_search(sourceContextIds, entry.sourceContextId);
|
||||
};
|
||||
|
||||
removeUnusedEntries(entires, notContainsId);
|
||||
@@ -126,28 +109,22 @@ public:
|
||||
ProjectChunkIds ids;
|
||||
ids.reserve(ids.size());
|
||||
|
||||
auto outputIterator = std::back_inserter(entries);
|
||||
|
||||
for (const IdPaths &idPath : idPaths)
|
||||
{
|
||||
ProjectChunkId id = idPath.id;
|
||||
|
||||
ids.push_back(id);
|
||||
|
||||
outputIterator = std::transform(idPath.sourceIds.begin(),
|
||||
idPath.sourceIds.end(),
|
||||
outputIterator,
|
||||
[&](SourceId sourceId) {
|
||||
std::ranges::transform(idPath.sourceIds, std::back_inserter(entries), [&](SourceId sourceId) {
|
||||
return WatcherEntry{id,
|
||||
sourceId.contextId(),
|
||||
sourceId,
|
||||
m_fileStatusCache.lastModifiedTime(
|
||||
sourceId)};
|
||||
m_fileStatusCache.lastModifiedTime(sourceId)};
|
||||
});
|
||||
}
|
||||
|
||||
std::sort(entries.begin(), entries.end());
|
||||
std::sort(ids.begin(), ids.end());
|
||||
std::ranges::sort(entries);
|
||||
std::ranges::sort(ids);
|
||||
|
||||
return {entries, ids};
|
||||
}
|
||||
@@ -191,9 +168,9 @@ public:
|
||||
SourceContextIds sourceContextIds = Utils::transform<SourceContextIds>(
|
||||
watcherEntries, &WatcherEntry::sourceContextId);
|
||||
|
||||
std::sort(sourceContextIds.begin(), sourceContextIds.end());
|
||||
sourceContextIds.erase(std::unique(sourceContextIds.begin(), sourceContextIds.end()),
|
||||
sourceContextIds.end());
|
||||
std::ranges::sort(sourceContextIds);
|
||||
auto removed = std::ranges::unique(sourceContextIds);
|
||||
sourceContextIds.erase(removed.begin(), removed.end());
|
||||
|
||||
return convertWatcherEntriesToDirectoryPathList(sourceContextIds);
|
||||
}
|
||||
@@ -203,11 +180,7 @@ public:
|
||||
WatcherEntries notWatchedEntries;
|
||||
notWatchedEntries.reserve(entries.size());
|
||||
|
||||
std::set_difference(entries.begin(),
|
||||
entries.end(),
|
||||
m_watchedEntries.cbegin(),
|
||||
m_watchedEntries.cend(),
|
||||
std::back_inserter(notWatchedEntries));
|
||||
std::ranges::set_difference(entries, m_watchedEntries, std::back_inserter(notWatchedEntries));
|
||||
|
||||
return notWatchedEntries;
|
||||
}
|
||||
@@ -217,11 +190,7 @@ public:
|
||||
SourceContextIds notWatchedDirectoryIds;
|
||||
notWatchedDirectoryIds.reserve(ids.size());
|
||||
|
||||
std::set_difference(ids.begin(),
|
||||
ids.end(),
|
||||
m_watchedEntries.cbegin(),
|
||||
m_watchedEntries.cend(),
|
||||
std::back_inserter(notWatchedDirectoryIds));
|
||||
std::ranges::set_difference(ids, m_watchedEntries, std::back_inserter(notWatchedDirectoryIds));
|
||||
|
||||
return notWatchedDirectoryIds;
|
||||
}
|
||||
@@ -232,10 +201,8 @@ public:
|
||||
WatcherEntries notAnymoreWatchedEntries;
|
||||
notAnymoreWatchedEntries.reserve(m_watchedEntries.size());
|
||||
|
||||
std::set_difference(m_watchedEntries.cbegin(),
|
||||
m_watchedEntries.cend(),
|
||||
newEntries.begin(),
|
||||
newEntries.end(),
|
||||
std::ranges::set_difference(m_watchedEntries,
|
||||
newEntries,
|
||||
std::back_inserter(notAnymoreWatchedEntries),
|
||||
compare);
|
||||
|
||||
@@ -245,11 +212,9 @@ public:
|
||||
template<typename Filter>
|
||||
WatcherEntries notAnymoreWatchedEntriesWithIds(const WatcherEntries &newEntries, Filter filter) const
|
||||
{
|
||||
auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less<WatcherEntry>());
|
||||
auto oldEntries = notAnymoreWatchedEntries(newEntries, std::ranges::less{});
|
||||
|
||||
auto newEnd = std::remove_if(oldEntries.begin(), oldEntries.end(), filter);
|
||||
|
||||
oldEntries.erase(newEnd, oldEntries.end());
|
||||
std::erase_if(oldEntries, filter);
|
||||
|
||||
return oldEntries;
|
||||
}
|
||||
@@ -259,11 +224,7 @@ public:
|
||||
WatcherEntries newWatchedEntries;
|
||||
newWatchedEntries.reserve(m_watchedEntries.size() + newEntries.size());
|
||||
|
||||
std::merge(m_watchedEntries.cbegin(),
|
||||
m_watchedEntries.cend(),
|
||||
newEntries.begin(),
|
||||
newEntries.end(),
|
||||
std::back_inserter(newWatchedEntries));
|
||||
std::ranges::merge(m_watchedEntries, newEntries, std::back_inserter(newWatchedEntries));
|
||||
|
||||
m_watchedEntries = std::move(newWatchedEntries);
|
||||
}
|
||||
@@ -273,14 +234,10 @@ public:
|
||||
SourceContextIds uniqueDirectoryIds;
|
||||
uniqueDirectoryIds.reserve(pathEntries.size());
|
||||
|
||||
auto compare = [](WatcherEntry first, WatcherEntry second) {
|
||||
return first.sourceContextId == second.sourceContextId;
|
||||
};
|
||||
|
||||
std::unique_copy(pathEntries.begin(),
|
||||
pathEntries.end(),
|
||||
std::ranges::unique_copy(pathEntries,
|
||||
std::back_inserter(uniqueDirectoryIds),
|
||||
compare);
|
||||
{},
|
||||
&WatcherEntry::sourceContextId);
|
||||
|
||||
return uniqueDirectoryIds;
|
||||
}
|
||||
@@ -294,15 +251,13 @@ public:
|
||||
|
||||
WatcherEntries removeIdsFromWatchedEntries(const ProjectPartIds &ids)
|
||||
{
|
||||
auto keep = [&](WatcherEntry entry) {
|
||||
return !std::binary_search(ids.begin(), ids.end(), entry.id);
|
||||
};
|
||||
auto keep = [&](WatcherEntry entry) { return !std::ranges::binary_search(ids, entry.id.id); };
|
||||
|
||||
auto found = std::stable_partition(m_watchedEntries.begin(), m_watchedEntries.end(), keep);
|
||||
auto removed = std::ranges::stable_partition(m_watchedEntries, keep);
|
||||
|
||||
WatcherEntries removedEntries(found, m_watchedEntries.end());
|
||||
WatcherEntries removedEntries(removed.begin(), removed.end());
|
||||
|
||||
m_watchedEntries.erase(found, m_watchedEntries.end());
|
||||
m_watchedEntries.erase(removed.begin(), removed.end());
|
||||
|
||||
return removedEntries;
|
||||
}
|
||||
@@ -312,10 +267,8 @@ public:
|
||||
WatcherEntries newWatchedEntries;
|
||||
newWatchedEntries.reserve(m_watchedEntries.size() - oldEntries.size());
|
||||
|
||||
std::set_difference(m_watchedEntries.cbegin(),
|
||||
m_watchedEntries.cend(),
|
||||
oldEntries.begin(),
|
||||
oldEntries.end(),
|
||||
std::ranges::set_difference(m_watchedEntries,
|
||||
oldEntries,
|
||||
std::back_inserter(newWatchedEntries));
|
||||
|
||||
m_watchedEntries = std::move(newWatchedEntries);
|
||||
@@ -332,19 +285,19 @@ public:
|
||||
WatcherEntries foundEntries;
|
||||
foundEntries.reserve(m_watchedEntries.size());
|
||||
|
||||
set_greedy_intersection_call(m_watchedEntries.begin(),
|
||||
m_watchedEntries.end(),
|
||||
sourceContextIds.begin(),
|
||||
sourceContextIds.end(),
|
||||
Utils::set_greedy_intersection(
|
||||
m_watchedEntries,
|
||||
sourceContextIds,
|
||||
[&](WatcherEntry &entry) {
|
||||
m_fileStatusCache.update(entry.sourceId);
|
||||
auto currentLastModified = m_fileStatusCache.lastModifiedTime(
|
||||
entry.sourceId);
|
||||
auto currentLastModified = m_fileStatusCache.lastModifiedTime(entry.sourceId);
|
||||
if (entry.lastModified < currentLastModified) {
|
||||
foundEntries.push_back(entry);
|
||||
entry.lastModified = currentLastModified;
|
||||
}
|
||||
});
|
||||
},
|
||||
{},
|
||||
&WatcherEntry::sourceContextId);
|
||||
|
||||
return foundEntries;
|
||||
}
|
||||
@@ -353,27 +306,32 @@ public:
|
||||
{
|
||||
auto sourceIds = Utils::transform<SourceIds>(entries, &WatcherEntry::sourceId);
|
||||
|
||||
std::sort(sourceIds.begin(), sourceIds.end());
|
||||
|
||||
sourceIds.erase(std::unique(sourceIds.begin(), sourceIds.end()), sourceIds.end());
|
||||
std::ranges::sort(sourceIds);
|
||||
auto removed = std::ranges::unique(sourceIds);
|
||||
sourceIds.erase(removed.begin(), removed.end());
|
||||
|
||||
return sourceIds;
|
||||
}
|
||||
|
||||
std::vector<IdPaths> idPathsForWatcherEntries(WatcherEntries &&foundEntries)
|
||||
{
|
||||
std::sort(foundEntries.begin(), foundEntries.end(), [](WatcherEntry first, WatcherEntry second) {
|
||||
return std::tie(first.id, first.sourceId) < std::tie(second.id, second.sourceId);
|
||||
std::ranges::sort(foundEntries, {}, [](const WatcherEntry &entry) {
|
||||
return std::tie(entry.id, entry.sourceId);
|
||||
});
|
||||
|
||||
std::vector<IdPaths> idPaths;
|
||||
idPaths.reserve(foundEntries.size());
|
||||
|
||||
if (foundEntries.size()) {
|
||||
idPaths.emplace_back(foundEntries.front().id, SourceIds{});
|
||||
|
||||
for (WatcherEntry entry : foundEntries) {
|
||||
if (idPaths.empty() || idPaths.back().id != entry.id)
|
||||
if (idPaths.back().id != entry.id)
|
||||
idPaths.emplace_back(entry.id, SourceIds{});
|
||||
|
||||
idPaths.back().sourceIds.push_back(entry.sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
return idPaths;
|
||||
}
|
||||
|
@@ -40,11 +40,15 @@ public:
|
||||
ProjectPartId id;
|
||||
SourceType sourceType;
|
||||
|
||||
auto operator<=>(const ProjectChunkId &) const = default;
|
||||
auto operator==(const ProjectChunkId &other) const
|
||||
{
|
||||
return std::tie(id, sourceType) == std::tie(other.id, other.sourceType);
|
||||
}
|
||||
|
||||
friend bool operator<(ProjectChunkId first, ProjectPartId second) { return first.id < second; }
|
||||
|
||||
friend bool operator<(ProjectPartId first, ProjectChunkId second) { return first < second.id; }
|
||||
auto operator<=>(const ProjectChunkId &other) const
|
||||
{
|
||||
return std::tie(id, sourceType) <=> std::tie(other.id, other.sourceType);
|
||||
}
|
||||
|
||||
template<typename String>
|
||||
friend void convertToString(String &string, const ProjectChunkId &id)
|
||||
@@ -112,16 +116,6 @@ public:
|
||||
<=> std::tie(second.sourceContextId, second.sourceId, second.id);
|
||||
}
|
||||
|
||||
friend auto operator<=>(SourceContextId sourceContextId, WatcherEntry entry)
|
||||
{
|
||||
return sourceContextId <=> entry.sourceContextId;
|
||||
}
|
||||
|
||||
friend auto operator<=>(WatcherEntry entry, SourceContextId sourceContextId)
|
||||
{
|
||||
return entry.sourceContextId <=> sourceContextId;
|
||||
}
|
||||
|
||||
operator SourceId() const { return sourceId; }
|
||||
|
||||
operator SourceContextId() const { return sourceContextId; }
|
||||
|
Reference in New Issue
Block a user