From 32c2906bf021d53e019db219e9a43268d9ba4e51 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Fri, 2 Dec 2016 11:01:48 +0100 Subject: [PATCH] logic: Improved performance of depending file path retrieval for refresh --- src/lib/data/PersistentStorage.cpp | 67 +++++++++++++++++++----------- src/lib/data/PersistentStorage.h | 1 - src/lib/data/SqliteStorage.cpp | 5 +++ src/lib/data/SqliteStorage.h | 1 + 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/src/lib/data/PersistentStorage.cpp b/src/lib/data/PersistentStorage.cpp index 8619e086..836da1c5 100644 --- a/src/lib/data/PersistentStorage.cpp +++ b/src/lib/data/PersistentStorage.cpp @@ -1148,28 +1148,31 @@ FilePath PersistentStorage::getFileNodePath(Id fileId) const std::set PersistentStorage::getDependingFilePathsForIncludes(const std::set& filePaths) { std::set dependingFilePaths; - for (const FilePath& filePath: filePaths) + std::set processedFileNodeIds; + + std::vector fileNodeIds; + for (const FilePath& filePath : filePaths) { - std::set dependingFilePathsSubset = getDependingFilePathsForIncludes(filePath); - dependingFilePaths.insert(dependingFilePathsSubset.begin(), dependingFilePathsSubset.end()); + fileNodeIds.push_back(getFileNodeId(filePath)); } - return dependingFilePaths; -} -std::set PersistentStorage::getDependingFilePathsForIncludes(const FilePath& filePath) -{ - std::set dependingFilePaths; - - std::vector incomingEdges = m_sqliteStorage.getEdgesByTargetType( - getFileNodeId(filePath), Edge::typeToInt(Edge::EDGE_INCLUDE) - ); - for (const StorageEdge& incomingEdge: incomingEdges) + while (fileNodeIds.size()) { - FilePath dependingFilePath = getFileNodePath(incomingEdge.sourceNodeId); - dependingFilePaths.insert(dependingFilePath); + std::vector incomingEdges = + m_sqliteStorage.getEdgesByTargetType(fileNodeIds, Edge::typeToInt(Edge::EDGE_INCLUDE)); - std::set dependingFilePathsSubset = getDependingFilePathsForIncludes(dependingFilePath); - dependingFilePaths.insert(dependingFilePathsSubset.begin(), dependingFilePathsSubset.end()); + processedFileNodeIds.insert(fileNodeIds.begin(), fileNodeIds.end()); + fileNodeIds.clear(); + + for (const StorageEdge& incomingEdge: incomingEdges) + { + dependingFilePaths.insert(getFileNodePath(incomingEdge.sourceNodeId)); + + if (processedFileNodeIds.find(incomingEdge.sourceNodeId) == processedFileNodeIds.end()) + { + fileNodeIds.push_back(incomingEdge.sourceNodeId); + } + } } return dependingFilePaths; @@ -1179,11 +1182,29 @@ std::set PersistentStorage::getDependingFilePathsForImports(const std: { std::map> fileIdToDependingFileIds; - for (const StorageEdge& importEdge: m_sqliteStorage.getEdgesByType(Edge::typeToInt(Edge::EDGE_IMPORT))) + std::multimap importEdgeTargetIdToSourceIds; + std::vector importedTargetIds; + + for (const StorageEdge& importEdge : m_sqliteStorage.getEdgesByType(Edge::typeToInt(Edge::EDGE_IMPORT))) { - for (const StorageSourceLocation& importedElementLoc: m_sqliteStorage.getSourceLocationsForElementId(importEdge.targetNodeId)) + importedTargetIds.push_back(importEdge.targetNodeId); + importEdgeTargetIdToSourceIds.emplace(importEdge.targetNodeId, importEdge.sourceNodeId); + } + + if (!importedTargetIds.size()) + { + return std::set(); + } + + for (const std::pair& p : + m_sqliteStorage.getSourceLocationsAndElementIdsForElementIds(importedTargetIds)) + { + std::pair ::const_iterator, std::multimap::const_iterator> ret = + importEdgeTargetIdToSourceIds.equal_range(p.second); + + for (std::multimap::const_iterator it = ret.first; it != ret.second; it++) { - fileIdToDependingFileIds[importedElementLoc.fileNodeId].insert(importEdge.sourceNodeId); + fileIdToDependingFileIds[p.first.fileNodeId].insert(it->second); } } @@ -1205,10 +1226,8 @@ std::set PersistentStorage::getDependingFilePathsForImports(const std: { for (Id dependingFileNodeId: it->second) { - const size_t countBeforeInsert = dependingFileNodeIds.size(); - dependingFileNodeIds.insert(dependingFileNodeId); - const size_t countAfterInsert = dependingFileNodeIds.size(); - if (countBeforeInsert != countAfterInsert) + bool inserted = dependingFileNodeIds.insert(dependingFileNodeId).second; + if (inserted) { tempWorking.insert(dependingFileNodeId); } diff --git a/src/lib/data/PersistentStorage.h b/src/lib/data/PersistentStorage.h index 58eaf3a9..d8558ce5 100644 --- a/src/lib/data/PersistentStorage.h +++ b/src/lib/data/PersistentStorage.h @@ -127,7 +127,6 @@ private: FilePath getFileNodePath(Id fileId) const; std::set getDependingFilePathsForIncludes(const std::set& filePaths); - std::set getDependingFilePathsForIncludes(const FilePath& filePath); std::set getDependingFilePathsForImports(const std::set& filePaths); Id getLastVisibleParentNodeId(const Id nodeId) const; diff --git a/src/lib/data/SqliteStorage.cpp b/src/lib/data/SqliteStorage.cpp index 65a237bc..ea35fc11 100644 --- a/src/lib/data/SqliteStorage.cpp +++ b/src/lib/data/SqliteStorage.cpp @@ -514,6 +514,11 @@ std::vector SqliteStorage::getEdgesByTargetType(Id targetId, int ty return getAll("WHERE target_node_id == " + std::to_string(targetId) + " AND type == " + std::to_string(type)); } +std::vector SqliteStorage::getEdgesByTargetType(const std::vector& targetIds, int type) const +{ + return getAll("WHERE target_node_id IN (" + utility::join(utility::toStrings(targetIds), ',') + ") AND type == " + std::to_string(type)); +} + StorageNode SqliteStorage::getNodeById(Id id) const { if (id != 0) diff --git a/src/lib/data/SqliteStorage.h b/src/lib/data/SqliteStorage.h index e7e012b6..f791b72e 100644 --- a/src/lib/data/SqliteStorage.h +++ b/src/lib/data/SqliteStorage.h @@ -86,6 +86,7 @@ public: std::vector getEdgesByType(int type) const; std::vector getEdgesBySourceType(Id sourceId, int type) const; std::vector getEdgesByTargetType(Id targetId, int type) const; + std::vector getEdgesByTargetType(const std::vector& targetIds, int type) const; StorageNode getNodeById(Id id) const; StorageNode getNodeBySerializedName(const std::string& serializedName) const;