From f9b43526f44404e680ab2d66b00d52e13c784a7d Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Fri, 3 Aug 2018 13:51:31 +0200 Subject: [PATCH] logic: improved performance of storing index to the database * batch inject occurrences * removed unnecessary destructor and keywords from storages --- src/lib/data/storage/IntermediateStorage.cpp | 12 +- src/lib/data/storage/IntermediateStorage.h | 43 +++--- src/lib/data/storage/PersistentStorage.cpp | 9 +- src/lib/data/storage/PersistentStorage.h | 136 +++++++++--------- src/lib/data/storage/Storage.cpp | 89 ++++++------ src/lib/data/storage/Storage.h | 3 +- .../storage/sqlite/SqliteIndexStorage.cpp | 39 +++-- .../data/storage/sqlite/SqliteIndexStorage.h | 1 + 8 files changed, 177 insertions(+), 155 deletions(-) diff --git a/src/lib/data/storage/IntermediateStorage.cpp b/src/lib/data/storage/IntermediateStorage.cpp index 8e91e7ac..8d5a10e6 100644 --- a/src/lib/data/storage/IntermediateStorage.cpp +++ b/src/lib/data/storage/IntermediateStorage.cpp @@ -7,10 +7,6 @@ IntermediateStorage::IntermediateStorage() { } -IntermediateStorage::~IntermediateStorage() -{ -} - void IntermediateStorage::clear() { m_nodes.clear(); @@ -205,6 +201,14 @@ void IntermediateStorage::addOccurrence(const StorageOccurrence& occurrence) } } +void IntermediateStorage::addOccurrences(const std::vector& occurrences) +{ + for (const StorageOccurrence& occurrence : occurrences) + { + addOccurrence(occurrence); + } +} + void IntermediateStorage::addComponentAccess(const StorageComponentAccessData& componentAccessData) { const std::wstring serialized = serialize(componentAccessData); diff --git a/src/lib/data/storage/IntermediateStorage.h b/src/lib/data/storage/IntermediateStorage.h index 5abb25ab..bf876c04 100644 --- a/src/lib/data/storage/IntermediateStorage.h +++ b/src/lib/data/storage/IntermediateStorage.h @@ -22,7 +22,6 @@ class IntermediateStorage: public Storage { public: IntermediateStorage(); - virtual ~IntermediateStorage(); void clear(); @@ -32,28 +31,28 @@ public: void setAllFilesIncomplete(); void setFilesWithErrorsIncomplete(); - virtual Id addNode(const StorageNodeData& nodeData) override; - virtual void addSymbol(const StorageSymbol& symbol) override; - virtual void addFile(const StorageFile& file) override; - virtual Id addEdge(const StorageEdgeData& edgeData) override; - virtual Id addLocalSymbol(const StorageLocalSymbolData& localSymbolData) override; - virtual Id addSourceLocation(const StorageSourceLocationData& sourceLocationData) override; - virtual void addOccurrence(const StorageOccurrence& occurrence) override; - virtual void addComponentAccess(const StorageComponentAccessData& componentAccessData) override; - virtual void addCommentLocation(const StorageCommentLocationData& commentLocationData) override; - virtual void addError(const StorageErrorData& errorData) override; - - virtual void forEachNode(std::function callback) const override; - virtual void forEachFile(std::function callback) const override; - virtual void forEachSymbol(std::function callback) const override; - virtual void forEachEdge(std::function callback) const override; - virtual void forEachLocalSymbol(std::function callback) const override; - virtual void forEachSourceLocation(std::function callback) const override; - virtual void forEachOccurrence(std::function callback) const override; - virtual void forEachComponentAccess(std::function callback) const override; - virtual void forEachCommentLocation(std::function callback) const override; - virtual void forEachError(std::function callback) const override; + Id addNode(const StorageNodeData& nodeData) override; + void addSymbol(const StorageSymbol& symbol) override; + void addFile(const StorageFile& file) override; + Id addEdge(const StorageEdgeData& edgeData) override; + Id addLocalSymbol(const StorageLocalSymbolData& localSymbolData) override; + Id addSourceLocation(const StorageSourceLocationData& sourceLocationData) override; + void addOccurrence(const StorageOccurrence& occurrence) override; + void addOccurrences(const std::vector& occurrences) override; + void addComponentAccess(const StorageComponentAccessData& componentAccessData) override; + void addCommentLocation(const StorageCommentLocationData& commentLocationData) override; + void addError(const StorageErrorData& errorData) override; + void forEachNode(std::function callback) const override; + void forEachFile(std::function callback) const override; + void forEachSymbol(std::function callback) const override; + void forEachEdge(std::function callback) const override; + void forEachLocalSymbol(std::function callback) const override; + void forEachSourceLocation(std::function callback) const override; + void forEachOccurrence(std::function callback) const override; + void forEachComponentAccess(std::function callback) const override; + void forEachCommentLocation(std::function callback) const override; + void forEachError(std::function callback) const override; // for conversion to and from 'SharedIntermediateStorage' diff --git a/src/lib/data/storage/PersistentStorage.cpp b/src/lib/data/storage/PersistentStorage.cpp index b32fd034..508c0096 100644 --- a/src/lib/data/storage/PersistentStorage.cpp +++ b/src/lib/data/storage/PersistentStorage.cpp @@ -46,10 +46,6 @@ PersistentStorage::PersistentStorage(const FilePath& dbPath, const FilePath& boo m_commandIndex.finishSetup(); } -PersistentStorage::~PersistentStorage() -{ -} - Id PersistentStorage::addNode(const StorageNodeData& data) { const StorageNode storedNode = m_sqliteIndexStorage.getNodeBySerializedName(data.serializedName); @@ -128,6 +124,11 @@ void PersistentStorage::addOccurrence(const StorageOccurrence& data) m_sqliteIndexStorage.addOccurrence(data); } +void PersistentStorage::addOccurrences(const std::vector& occurrences) +{ + m_sqliteIndexStorage.addOccurrences(occurrences); +} + void PersistentStorage::addComponentAccess(const StorageComponentAccessData& data) { m_sqliteIndexStorage.addComponentAccess(data); diff --git a/src/lib/data/storage/PersistentStorage.h b/src/lib/data/storage/PersistentStorage.h index c4925b41..6728ee1b 100644 --- a/src/lib/data/storage/PersistentStorage.h +++ b/src/lib/data/storage/PersistentStorage.h @@ -18,32 +18,32 @@ class PersistentStorage { public: PersistentStorage(const FilePath& dbPath, const FilePath& bookmarkPath); - virtual ~PersistentStorage(); - virtual Id addNode(const StorageNodeData& data) override; - virtual void addSymbol(const StorageSymbol& data) override; - virtual void addFile(const StorageFile& data) override; - virtual Id addEdge(const StorageEdgeData& data) override; - virtual Id addLocalSymbol(const StorageLocalSymbolData& data) override; - virtual Id addSourceLocation(const StorageSourceLocationData& data) override; - virtual void addOccurrence(const StorageOccurrence& data) override; - virtual void addComponentAccess(const StorageComponentAccessData& data) override; - virtual void addCommentLocation(const StorageCommentLocationData& data) override; - virtual void addError(const StorageErrorData& data) override; + Id addNode(const StorageNodeData& data) override; + void addSymbol(const StorageSymbol& data) override; + void addFile(const StorageFile& data) override; + Id addEdge(const StorageEdgeData& data) override; + Id addLocalSymbol(const StorageLocalSymbolData& data) override; + Id addSourceLocation(const StorageSourceLocationData& data) override; + void addOccurrence(const StorageOccurrence& data) override; + void addOccurrences(const std::vector& occurrences) override; + void addComponentAccess(const StorageComponentAccessData& data) override; + void addCommentLocation(const StorageCommentLocationData& data) override; + void addError(const StorageErrorData& data) override; - virtual void forEachNode(std::function callback) const override; - virtual void forEachFile(std::function callback) const override; - virtual void forEachSymbol(std::function callback) const override; - virtual void forEachEdge(std::function callback) const override; - virtual void forEachLocalSymbol(std::function callback) const override; - virtual void forEachSourceLocation(std::function callback) const override; - virtual void forEachOccurrence(std::function callback) const override; - virtual void forEachComponentAccess(std::function callback) const override; - virtual void forEachCommentLocation(std::function callback) const override; - virtual void forEachError(std::function callback) const override; + void forEachNode(std::function callback) const override; + void forEachFile(std::function callback) const override; + void forEachSymbol(std::function callback) const override; + void forEachEdge(std::function callback) const override; + void forEachLocalSymbol(std::function callback) const override; + void forEachSourceLocation(std::function callback) const override; + void forEachOccurrence(std::function callback) const override; + void forEachComponentAccess(std::function callback) const override; + void forEachCommentLocation(std::function callback) const override; + void forEachError(std::function callback) const override; - virtual void startInjection() override; - virtual void finishInjection() override; + void startInjection() override; + void finishInjection() override; void setMode(const SqliteIndexStorage::StorageModeType mode); @@ -75,82 +75,82 @@ public: void optimizeMemory(); // StorageAccess implementation - virtual Id getNodeIdForFileNode(const FilePath& filePath) const override; - virtual Id getNodeIdForNameHierarchy(const NameHierarchy& nameHierarchy) const override; - virtual std::vector getNodeIdsForNameHierarchies(const std::vector nameHierarchies) const override; + Id getNodeIdForFileNode(const FilePath& filePath) const override; + Id getNodeIdForNameHierarchy(const NameHierarchy& nameHierarchy) const override; + std::vector getNodeIdsForNameHierarchies(const std::vector nameHierarchies) const override; - virtual NameHierarchy getNameHierarchyForNodeId(Id nodeId) const override; - virtual std::vector getNameHierarchiesForNodeIds(const std::vector& nodeIds) const override; - virtual std::map> getNodeIdToParentFileMap(const std::vector& nodeIds) const override; + NameHierarchy getNameHierarchyForNodeId(Id nodeId) const override; + std::vector getNameHierarchiesForNodeIds(const std::vector& nodeIds) const override; + std::map> getNodeIdToParentFileMap(const std::vector& nodeIds) const override; - virtual NodeType getNodeTypeForNodeWithId(Id nodeId) const override; + NodeType getNodeTypeForNodeWithId(Id nodeId) const override; - virtual Id getIdForEdge( + Id getIdForEdge( Edge::EdgeType type, const NameHierarchy& fromNameHierarchy, const NameHierarchy& toNameHierarchy) const override; - virtual StorageEdge getEdgeById(Id edgeId) const override; + StorageEdge getEdgeById(Id edgeId) const override; - virtual std::shared_ptr getFullTextSearchLocations( + std::shared_ptr getFullTextSearchLocations( const std::wstring& searchTerm, bool caseSensitive) const override; - virtual std::vector getAutocompletionMatches(const std::wstring& query, NodeTypeSet acceptedNodeTypes) const override; + std::vector getAutocompletionMatches(const std::wstring& query, NodeTypeSet acceptedNodeTypes) const override; std::vector getAutocompletionSymbolMatches( const std::wstring& query, const NodeTypeSet& acceptedNodeTypes, size_t maxResultsCount, size_t maxBestScoredResultsLength) const; std::vector getAutocompletionFileMatches(const std::wstring& query, size_t maxResultsCount) const; std::vector getAutocompletionCommandMatches(const std::wstring& query, NodeTypeSet acceptedNodeTypes) const; - virtual std::vector getSearchMatchesForTokenIds(const std::vector& elementIds) const override; + std::vector getSearchMatchesForTokenIds(const std::vector& elementIds) const override; - virtual std::shared_ptr getGraphForAll() const override; - virtual std::shared_ptr getGraphForNodeTypes(NodeTypeSet nodeTypes) const override; - virtual std::shared_ptr getGraphForActiveTokenIds( + std::shared_ptr getGraphForAll() const override; + std::shared_ptr getGraphForNodeTypes(NodeTypeSet nodeTypes) const override; + std::shared_ptr getGraphForActiveTokenIds( const std::vector& tokenIds, const std::vector& expandedNodeIds, bool* isActiveNamespace = nullptr) const override; - virtual std::shared_ptr getGraphForChildrenOfNodeId(Id nodeId) const override; - virtual std::shared_ptr getGraphForTrail(Id originId, Id targetId, Edge::TypeMask trailType, size_t depth) const override; + std::shared_ptr getGraphForChildrenOfNodeId(Id nodeId) const override; + std::shared_ptr getGraphForTrail(Id originId, Id targetId, Edge::TypeMask trailType, size_t depth) const override; - virtual std::vector getActiveTokenIdsForId(Id tokenId, Id* declarationId) const override; - virtual std::vector getNodeIdsForLocationIds(const std::vector& locationIds) const override; + std::vector getActiveTokenIdsForId(Id tokenId, Id* declarationId) const override; + std::vector getNodeIdsForLocationIds(const std::vector& locationIds) const override; - virtual std::shared_ptr getSourceLocationsForTokenIds(const std::vector& tokenIds) const override; - virtual std::shared_ptr getSourceLocationsForLocationIds(const std::vector& locationIds) const override; + std::shared_ptr getSourceLocationsForTokenIds(const std::vector& tokenIds) const override; + std::shared_ptr getSourceLocationsForLocationIds(const std::vector& locationIds) const override; - virtual std::shared_ptr getSourceLocationsForFile(const FilePath& filePath) const override; - virtual std::shared_ptr getSourceLocationsForLinesInFile( + std::shared_ptr getSourceLocationsForFile(const FilePath& filePath) const override; + std::shared_ptr getSourceLocationsForLinesInFile( const FilePath& filePath, size_t startLine, size_t endLine) const override; - virtual std::shared_ptr getSourceLocationsOfTypeInFile( + std::shared_ptr getSourceLocationsOfTypeInFile( const FilePath& filePath, LocationType type) const override; - virtual std::shared_ptr getCommentLocationsInFile(const FilePath& filePath) const override; + std::shared_ptr getCommentLocationsInFile(const FilePath& filePath) const override; - virtual std::shared_ptr getFileContent(const FilePath& filePath) const override; + std::shared_ptr getFileContent(const FilePath& filePath) const override; - virtual FileInfo getFileInfoForFileId(Id id) const override; + FileInfo getFileInfoForFileId(Id id) const override; - virtual FileInfo getFileInfoForFilePath(const FilePath& filePath) const override; - virtual std::vector getFileInfosForFilePaths(const std::vector& filePaths) const override; + FileInfo getFileInfoForFilePath(const FilePath& filePath) const override; + std::vector getFileInfosForFilePaths(const std::vector& filePaths) const override; - virtual StorageStats getStorageStats() const override; + StorageStats getStorageStats() const override; - virtual ErrorCountInfo getErrorCount() const override; - virtual std::vector getErrorsLimited(const ErrorFilter& filter) const override; - virtual std::vector getErrorsForFileLimited( + ErrorCountInfo getErrorCount() const override; + std::vector getErrorsLimited(const ErrorFilter& filter) const override; + std::vector getErrorsForFileLimited( const ErrorFilter& filter, const FilePath& filePath) const override; - virtual std::shared_ptr getErrorSourceLocations( + std::shared_ptr getErrorSourceLocations( const std::vector& errors) const override; - virtual Id addNodeBookmark(const NodeBookmark& bookmark) override; - virtual Id addEdgeBookmark(const EdgeBookmark& bookmark) override; - virtual Id addBookmarkCategory(const std::wstring& categoryName) override; + Id addNodeBookmark(const NodeBookmark& bookmark) override; + Id addEdgeBookmark(const EdgeBookmark& bookmark) override; + Id addBookmarkCategory(const std::wstring& categoryName) override; - virtual void updateBookmark(const Id bookmarkId, const std::wstring& name, const std::wstring& comment, const std::wstring& categoryName) override; - virtual void removeBookmark(const Id id) override; - virtual void removeBookmarkCategory(const Id id) override; + void updateBookmark(const Id bookmarkId, const std::wstring& name, const std::wstring& comment, const std::wstring& categoryName) override; + void removeBookmark(const Id id) override; + void removeBookmarkCategory(const Id id) override; - virtual std::vector getAllNodeBookmarks() const override; - virtual std::vector getAllEdgeBookmarks() const override; - virtual std::vector getAllBookmarkCategories() const override; + std::vector getAllNodeBookmarks() const override; + std::vector getAllEdgeBookmarks() const override; + std::vector getAllBookmarkCategories() const override; - virtual TooltipInfo getTooltipInfoForTokenIds(const std::vector& tokenIds, TooltipOrigin origin) const override; + TooltipInfo getTooltipInfoForTokenIds(const std::vector& tokenIds, TooltipOrigin origin) const override; TooltipSnippet getTooltipSnippetForNode(const StorageNode& node) const; - virtual TooltipInfo getTooltipInfoForSourceLocationIdsAndLocalSymbolIds( + TooltipInfo getTooltipInfoForSourceLocationIdsAndLocalSymbolIds( const std::vector& locationIds, const std::vector& localSymbolIds) const override; private: diff --git a/src/lib/data/storage/Storage.cpp b/src/lib/data/storage/Storage.cpp index a4305f4e..d49b6f48 100644 --- a/src/lib/data/storage/Storage.cpp +++ b/src/lib/data/storage/Storage.cpp @@ -18,10 +18,6 @@ Storage::Storage() { } -Storage::~Storage() -{ -} - void Storage::inject(Storage* injected) { std::lock_guard lock(m_dataMutex); @@ -36,7 +32,7 @@ void Storage::inject(Storage* injected) } ); - std::unordered_map injectedIdToOwnId; + std::unordered_map injectedIdToOwnElementId; injected->forEachNode( [&](const StorageNode& injectedData) @@ -44,7 +40,7 @@ void Storage::inject(Storage* injected) const Id ownId = addNode(injectedData); if (ownId != 0) { - injectedIdToOwnId[injectedData.id] = ownId; + injectedIdToOwnElementId[injectedData.id] = ownId; } } ); @@ -53,8 +49,8 @@ void Storage::inject(Storage* injected) [&](const StorageFile& injectedData) { std::unordered_map::const_iterator it; - it = injectedIdToOwnId.find(injectedData.id); - if (it != injectedIdToOwnId.end()) + it = injectedIdToOwnElementId.find(injectedData.id); + if (it != injectedIdToOwnElementId.end()) { const Id ownId = it->second; addFile(StorageFile(ownId, injectedData.filePath, injectedData.modificationTime, injectedData.indexed, injectedData.complete)); @@ -66,8 +62,8 @@ void Storage::inject(Storage* injected) [&](const StorageSymbol& injectedData) { std::unordered_map::const_iterator it; - it = injectedIdToOwnId.find(injectedData.id); - if (it != injectedIdToOwnId.end()) + it = injectedIdToOwnElementId.find(injectedData.id); + if (it != injectedIdToOwnElementId.end()) { const Id ownId = it->second; addSymbol(StorageSymbol(ownId, injectedData.definitionKind)); @@ -79,15 +75,15 @@ void Storage::inject(Storage* injected) [&](const StorageEdge& injectedData) { std::unordered_map::const_iterator it; - it = injectedIdToOwnId.find(injectedData.sourceNodeId); - if (it == injectedIdToOwnId.end()) + it = injectedIdToOwnElementId.find(injectedData.sourceNodeId); + if (it == injectedIdToOwnElementId.end()) { return; } const Id ownSourceId = it->second; - it = injectedIdToOwnId.find(injectedData.targetNodeId); - if (it == injectedIdToOwnId.end()) + it = injectedIdToOwnElementId.find(injectedData.targetNodeId); + if (it == injectedIdToOwnElementId.end()) { return; } @@ -97,7 +93,7 @@ void Storage::inject(Storage* injected) if (ownId != 0) { - injectedIdToOwnId[injectedData.id] = ownId; + injectedIdToOwnElementId[injectedData.id] = ownId; } } ); @@ -108,17 +104,19 @@ void Storage::inject(Storage* injected) const Id ownId = addLocalSymbol(injectedData); if (ownId != 0) { - injectedIdToOwnId[injectedData.id] = ownId; + injectedIdToOwnElementId[injectedData.id] = ownId; } } ); + std::unordered_map injectedIdToOwnSourceLocationId; + injected->forEachSourceLocation( [&](const StorageSourceLocation& injectedData) { std::unordered_map::const_iterator it; - it = injectedIdToOwnId.find(injectedData.fileNodeId); - if (it != injectedIdToOwnId.end()) + it = injectedIdToOwnElementId.find(injectedData.fileNodeId); + if (it != injectedIdToOwnElementId.end()) { const Id ownFileNodeId = it->second; @@ -132,40 +130,49 @@ void Storage::inject(Storage* injected) )); if (ownId != 0) { - injectedIdToOwnId[injectedData.id] = ownId; + injectedIdToOwnSourceLocationId[injectedData.id] = ownId; } } } ); - injected->forEachOccurrence( - [&](const StorageOccurrence& injectedData) - { - std::unordered_map::const_iterator it; - it = injectedIdToOwnId.find(injectedData.elementId); - if (it == injectedIdToOwnId.end()) + { + std::vector occurrences; + injected->forEachOccurrence( + [&](const StorageOccurrence& injectedData) { - return; - } - const Id ownElementId = it->second; + std::unordered_map::const_iterator it; + it = injectedIdToOwnElementId.find(injectedData.elementId); + if (it == injectedIdToOwnElementId.end()) + { + return; + } + const Id ownElementId = it->second; - it = injectedIdToOwnId.find(injectedData.sourceLocationId); - if (it == injectedIdToOwnId.end()) - { - return; - } - const Id ownSourceLocationId = it->second; + it = injectedIdToOwnSourceLocationId.find(injectedData.sourceLocationId); + if (it == injectedIdToOwnSourceLocationId.end()) + { + return; + } + const Id ownSourceLocationId = it->second; - addOccurrence(StorageOccurrence(ownElementId, ownSourceLocationId)); - } - ); + occurrences.push_back(StorageOccurrence(ownElementId, ownSourceLocationId)); + if (occurrences.size() >= 100) + { + addOccurrences(occurrences); + occurrences.clear(); + } + } + ); + addOccurrences(occurrences); + } injected->forEachComponentAccess( [&](const StorageComponentAccessData& injectedData) { std::unordered_map::const_iterator it; - it = injectedIdToOwnId.find(injectedData.nodeId); - if (it == injectedIdToOwnId.end()) + it = injectedIdToOwnElementId.find(injectedData.nodeId); + if (it == injectedIdToOwnElementId.end()) { return; } @@ -179,8 +186,8 @@ void Storage::inject(Storage* injected) [&](const StorageCommentLocationData& injectedData) { std::unordered_map::const_iterator it; - it = injectedIdToOwnId.find(injectedData.fileNodeId); - if (it == injectedIdToOwnId.end()) + it = injectedIdToOwnElementId.find(injectedData.fileNodeId); + if (it == injectedIdToOwnElementId.end()) { return; } diff --git a/src/lib/data/storage/Storage.h b/src/lib/data/storage/Storage.h index f1ab5e8c..cfa94f17 100644 --- a/src/lib/data/storage/Storage.h +++ b/src/lib/data/storage/Storage.h @@ -21,7 +21,7 @@ class Storage { public: Storage(); - virtual ~Storage(); + virtual ~Storage() = default; virtual Id addNode(const StorageNodeData& data) = 0; virtual void addSymbol(const StorageSymbol& data) = 0; @@ -30,6 +30,7 @@ public: virtual Id addLocalSymbol(const StorageLocalSymbolData& data) = 0; virtual Id addSourceLocation(const StorageSourceLocationData& data) = 0; virtual void addOccurrence(const StorageOccurrence& data) = 0; + virtual void addOccurrences(const std::vector& occurrences) = 0; virtual void addComponentAccess(const StorageComponentAccessData& data) = 0; virtual void addCommentLocation(const StorageCommentLocationData& data) = 0; virtual void addError(const StorageErrorData& data) = 0; diff --git a/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp b/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp index 9fff36ff..29a0d0df 100644 --- a/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp +++ b/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp @@ -172,17 +172,6 @@ StorageSourceLocation SqliteIndexStorage::addSourceLocation(const StorageSourceL bool SqliteIndexStorage::addOccurrence(const StorageOccurrence& data) { - { - m_checkOccurrenceExistsStmt.bind(1, int(data.elementId)); - m_checkOccurrenceExistsStmt.bind(2, int(data.sourceLocationId)); - - const int checkResult = executeStatementScalar(m_checkOccurrenceExistsStmt, 0); - m_checkOccurrenceExistsStmt.reset(); - if (checkResult != 0) - { - return false; - } - } { m_insertOccurrenceStmt.bind(1, int(data.elementId)); m_insertOccurrenceStmt.bind(2, int(data.sourceLocationId)); @@ -192,6 +181,29 @@ bool SqliteIndexStorage::addOccurrence(const StorageOccurrence& data) return true; } +bool SqliteIndexStorage::addOccurrences(const std::vector& occurrences) +{ + if (!occurrences.empty()) + { + std::string stmt = "INSERT OR IGNORE INTO occurrence(element_id, source_location_id) VALUES"; + { + bool isFirst = true; + for (const StorageOccurrence& occurrence : occurrences) + { + if (!isFirst) + { + stmt += ","; + } + isFirst = false; + stmt += "(" + std::to_string(occurrence.elementId) + "," + std::to_string(occurrence.sourceLocationId) + ")"; + } + stmt += ";"; + } + return executeStatement(stmt); + } + return true; +} + StorageComponentAccess SqliteIndexStorage::addComponentAccess(const StorageComponentAccessData& data) { Id id = getComponentAccessByNodeId(data.nodeId).id; @@ -1107,11 +1119,8 @@ void SqliteIndexStorage::setupPrecompiledStatements() m_insertSourceLocationStmt = m_database.compileStatement( "INSERT INTO source_location(id, file_node_id, start_line, start_column, end_line, end_column, type) VALUES(NULL, ?, ?, ?, ?, ?, ?);" ); - m_checkOccurrenceExistsStmt = m_database.compileStatement( - "SELECT EXISTS(SELECT * FROM occurrence WHERE element_id = ? AND source_location_id = ? LIMIT 1);" - ); m_insertOccurrenceStmt = m_database.compileStatement( - "INSERT INTO occurrence(element_id, source_location_id) VALUES(?, ?);" + "INSERT OR IGNORE INTO occurrence(element_id, source_location_id) VALUES(?, ?);" ); m_insertComponentAccessStmt = m_database.compileStatement( "INSERT INTO component_access(id, node_id, type) VALUES(NULL, ?, ?);" diff --git a/src/lib/data/storage/sqlite/SqliteIndexStorage.h b/src/lib/data/storage/sqlite/SqliteIndexStorage.h index 0aed2aae..b1783a52 100644 --- a/src/lib/data/storage/sqlite/SqliteIndexStorage.h +++ b/src/lib/data/storage/sqlite/SqliteIndexStorage.h @@ -46,6 +46,7 @@ public: StorageLocalSymbol addLocalSymbol(const StorageLocalSymbolData& data); StorageSourceLocation addSourceLocation(const StorageSourceLocationData& data); bool addOccurrence(const StorageOccurrence& data); + bool addOccurrences(const std::vector& occurrences); StorageComponentAccess addComponentAccess(const StorageComponentAccessData& data); StorageCommentLocation addCommentLocation(const StorageCommentLocationData& data); StorageError addError(const StorageErrorData& data);