data: Improved injection performance with batched insertions

* add InsertBatchStatement inserting any number as multiples
* switched Storage injection interface to containers
This commit is contained in:
Eberhard Graether
2018-10-03 01:15:27 +02:00
parent 15e66758df
commit f060b6042d
11 changed files with 716 additions and 512 deletions
+54 -80
View File
@@ -121,11 +121,27 @@ std::pair<Id, bool> IntermediateStorage::addNode(const StorageNodeData& nodeData
return std::make_pair(nodeId, true); return std::make_pair(nodeId, true);
} }
std::vector<Id> IntermediateStorage::addNodes(const std::vector<StorageNode>& nodes)
{
std::vector<Id> nodeIds;
nodeIds.reserve(nodes.size());
for (const StorageNode& node : nodes)
{
nodeIds.emplace_back(addNode(node).first);
}
return nodeIds;
}
void IntermediateStorage::addSymbol(const StorageSymbol& symbol) void IntermediateStorage::addSymbol(const StorageSymbol& symbol)
{ {
m_symbols.push_back(symbol); m_symbols.push_back(symbol);
} }
void IntermediateStorage::addSymbols(const std::vector<StorageSymbol>& symbols)
{
m_symbols.insert(m_symbols.end(), symbols.begin(), symbols.end());
}
void IntermediateStorage::addFile(const StorageFile& file) void IntermediateStorage::addFile(const StorageFile& file)
{ {
auto it = m_filesIndex.find(file); auto it = m_filesIndex.find(file);
@@ -164,6 +180,17 @@ Id IntermediateStorage::addEdge(const StorageEdgeData& edgeData)
return edgeId; return edgeId;
} }
std::vector<Id> IntermediateStorage::addEdges(const std::vector<StorageEdge>& edges)
{
std::vector<Id> edgeIds;
edgeIds.reserve(edges.size());
for (const StorageEdge& edge : edges)
{
edgeIds.emplace_back(addEdge(edge));
}
return edgeIds;
}
Id IntermediateStorage::addLocalSymbol(const StorageLocalSymbolData& localSymbolData) Id IntermediateStorage::addLocalSymbol(const StorageLocalSymbolData& localSymbolData)
{ {
auto it = m_localSymbols.find(StorageLocalSymbol(0, localSymbolData)); auto it = m_localSymbols.find(StorageLocalSymbol(0, localSymbolData));
@@ -177,6 +204,17 @@ Id IntermediateStorage::addLocalSymbol(const StorageLocalSymbolData& localSymbol
return localSymbolId; return localSymbolId;
} }
std::vector<Id> IntermediateStorage::addLocalSymbols(const std::set<StorageLocalSymbol>& symbols)
{
std::vector<Id> symbolIds;
symbolIds.reserve(symbols.size());
for (const StorageLocalSymbol& symbol : symbols)
{
symbolIds.emplace_back(addLocalSymbol(symbol));
}
return symbolIds;
}
Id IntermediateStorage::addSourceLocation(const StorageSourceLocationData& sourceLocationData) Id IntermediateStorage::addSourceLocation(const StorageSourceLocationData& sourceLocationData)
{ {
auto it = m_sourceLocations.find(StorageSourceLocation(0, sourceLocationData)); auto it = m_sourceLocations.find(StorageSourceLocation(0, sourceLocationData));
@@ -190,6 +228,17 @@ Id IntermediateStorage::addSourceLocation(const StorageSourceLocationData& sourc
return sourceLocationId; return sourceLocationId;
} }
std::vector<Id> IntermediateStorage::addSourceLocations(const std::vector<StorageSourceLocation>& locations)
{
std::vector<Id> locationIds;
locationIds.reserve(locations.size());
for (const StorageSourceLocation& location : locations)
{
locationIds.emplace_back(addSourceLocation(location));
}
return locationIds;
}
void IntermediateStorage::addOccurrence(const StorageOccurrence& occurrence) void IntermediateStorage::addOccurrence(const StorageOccurrence& occurrence)
{ {
m_occurrences.emplace(occurrence); m_occurrences.emplace(occurrence);
@@ -205,6 +254,11 @@ void IntermediateStorage::addComponentAccess(const StorageComponentAccess& compo
m_componentAccesses.emplace(componentAccess); m_componentAccesses.emplace(componentAccess);
} }
void IntermediateStorage::addComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses)
{
m_componentAccesses.insert(componentAccesses.begin(), componentAccesses.end());
}
void IntermediateStorage::addCommentLocation(const StorageCommentLocationData& commentLocationData) void IntermediateStorage::addCommentLocation(const StorageCommentLocationData& commentLocationData)
{ {
m_commentLocations.emplace(commentLocationData); m_commentLocations.emplace(commentLocationData);
@@ -219,86 +273,6 @@ void IntermediateStorage::addError(const StorageErrorData& errorData)
} }
} }
void IntermediateStorage::forEachNode(std::function<void(const StorageNode& /*data*/)> callback) const
{
for (const StorageNode& node : m_nodes)
{
callback(node);
}
}
void IntermediateStorage::forEachFile(std::function<void(const StorageFile& /*data*/)> callback) const
{
for (const StorageFile& file : m_files)
{
callback(file);
}
}
void IntermediateStorage::forEachSymbol(std::function<void(const StorageSymbol& /*data*/)> callback) const
{
for (const StorageSymbol& symbol : m_symbols)
{
callback(symbol);
}
}
void IntermediateStorage::forEachEdge(std::function<void(const StorageEdge& /*data*/)> callback) const
{
for (const StorageEdge& edge : m_edges)
{
callback(edge);
}
}
void IntermediateStorage::forEachLocalSymbol(std::function<void(const StorageLocalSymbol& /*data*/)> callback) const
{
for (const StorageLocalSymbol& localSymbol : m_localSymbols)
{
callback(localSymbol);
}
}
void IntermediateStorage::forEachSourceLocation(std::function<void(const StorageSourceLocation& /*data*/)> callback) const
{
for (const StorageSourceLocation& sourceLocation : m_sourceLocations)
{
callback(sourceLocation);
}
}
void IntermediateStorage::forEachOccurrence(std::function<void(const StorageOccurrence& /*data*/)> callback) const
{
for (const StorageOccurrence& occurrence : m_occurrences)
{
callback(occurrence);
}
}
void IntermediateStorage::forEachComponentAccess(std::function<void(const StorageComponentAccess& /*data*/)> callback) const
{
for (const StorageComponentAccess& componentAccess : m_componentAccesses)
{
callback(componentAccess);
}
}
void IntermediateStorage::forEachCommentLocation(std::function<void(const StorageCommentLocationData& /*data*/)> callback) const
{
for (const StorageCommentLocationData& commentLocation : m_commentLocations)
{
callback(commentLocation);
}
}
void IntermediateStorage::forEachError(std::function<void(const StorageErrorData& /*data*/)> callback) const
{
for (const StorageErrorData& error : m_errors)
{
callback(error);
}
}
const std::vector<StorageNode>& IntermediateStorage::getStorageNodes() const const std::vector<StorageNode>& IntermediateStorage::getStorageNodes() const
{ {
return m_nodes; return m_nodes;
+16 -23
View File
@@ -31,40 +31,33 @@ public:
void setFilesWithErrorsIncomplete(); void setFilesWithErrorsIncomplete();
std::pair<Id, bool> addNode(const StorageNodeData& nodeData) override; std::pair<Id, bool> addNode(const StorageNodeData& nodeData) override;
std::vector<Id> addNodes(const std::vector<StorageNode>& nodes) override;
void addSymbol(const StorageSymbol& symbol) override; void addSymbol(const StorageSymbol& symbol) override;
void addSymbols(const std::vector<StorageSymbol>& symbols) override;
void addFile(const StorageFile& file) override; void addFile(const StorageFile& file) override;
Id addEdge(const StorageEdgeData& edgeData) override; Id addEdge(const StorageEdgeData& edgeData) override;
std::vector<Id> addEdges(const std::vector<StorageEdge>& edges) override;
Id addLocalSymbol(const StorageLocalSymbolData& localSymbolData) override; Id addLocalSymbol(const StorageLocalSymbolData& localSymbolData) override;
std::vector<Id> addLocalSymbols(const std::set<StorageLocalSymbol>& symbols) override;
Id addSourceLocation(const StorageSourceLocationData& sourceLocationData) override; Id addSourceLocation(const StorageSourceLocationData& sourceLocationData) override;
std::vector<Id> addSourceLocations(const std::vector<StorageSourceLocation>& locations) override;
void addOccurrence(const StorageOccurrence& occurrence) override; void addOccurrence(const StorageOccurrence& occurrence) override;
void addOccurrences(const std::vector<StorageOccurrence>& occurrences) override; void addOccurrences(const std::vector<StorageOccurrence>& occurrences) override;
void addComponentAccess(const StorageComponentAccess& componentAccess) override; void addComponentAccess(const StorageComponentAccess& componentAccess) override;
void addComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses) override;
void addCommentLocation(const StorageCommentLocationData& commentLocationData) override; void addCommentLocation(const StorageCommentLocationData& commentLocationData) override;
void addError(const StorageErrorData& errorData) override; void addError(const StorageErrorData& errorData) override;
void forEachNode(std::function<void(const StorageNode& /*data*/)> callback) const override; const std::vector<StorageNode>& getStorageNodes() const override;
void forEachFile(std::function<void(const StorageFile& /*data*/)> callback) const override; const std::vector<StorageFile>& getStorageFiles() const override;
void forEachSymbol(std::function<void(const StorageSymbol& /*data*/)> callback) const override; const std::vector<StorageSymbol>& getStorageSymbols() const override;
void forEachEdge(std::function<void(const StorageEdge& /*data*/)> callback) const override; const std::vector<StorageEdge>& getStorageEdges() const override;
void forEachLocalSymbol(std::function<void(const StorageLocalSymbol& /*data*/)> callback) const override; const std::set<StorageLocalSymbol>& getStorageLocalSymbols() const override;
void forEachSourceLocation(std::function<void(const StorageSourceLocation& /*data*/)> callback) const override; const std::set<StorageSourceLocation>& getStorageSourceLocations() const override;
void forEachOccurrence(std::function<void(const StorageOccurrence& /*data*/)> callback) const override; const std::set<StorageOccurrence>& getStorageOccurrences() const override;
void forEachComponentAccess(std::function<void(const StorageComponentAccess& /*data*/)> callback) const override; const std::set<StorageComponentAccess>& getComponentAccesses() const override;
void forEachCommentLocation(std::function<void(const StorageCommentLocationData& /*data*/)> callback) const override; const std::set<StorageCommentLocationData>& getCommentLocations() const override;
void forEachError(std::function<void(const StorageErrorData& /*data*/)> callback) const override; const std::vector<StorageErrorData>& getErrors() const override;
// for conversion to and from 'SharedIntermediateStorage'
const std::vector<StorageNode>& getStorageNodes() const;
const std::vector<StorageFile>& getStorageFiles() const;
const std::vector<StorageSymbol>& getStorageSymbols() const;
const std::vector<StorageEdge>& getStorageEdges() const;
const std::set<StorageLocalSymbol>& getStorageLocalSymbols() const;
const std::set<StorageSourceLocation>& getStorageSourceLocations() const;
const std::set<StorageOccurrence>& getStorageOccurrences() const;
const std::set<StorageComponentAccess>& getComponentAccesses() const;
const std::set<StorageCommentLocationData>& getCommentLocations() const;
const std::vector<StorageErrorData>& getErrors() const;
void setStorageNodes(std::vector<StorageNode> storageNodes); void setStorageNodes(std::vector<StorageNode> storageNodes);
void setStorageFiles(std::vector<StorageFile> storageFiles); void setStorageFiles(std::vector<StorageFile> storageFiles);
+60 -50
View File
@@ -48,7 +48,12 @@ PersistentStorage::PersistentStorage(const FilePath& dbPath, const FilePath& boo
std::pair<Id, bool> PersistentStorage::addNode(const StorageNodeData& data) std::pair<Id, bool> PersistentStorage::addNode(const StorageNodeData& data)
{ {
return std::make_pair(m_sqliteIndexStorage.addNode(data).id, true); return std::make_pair(m_sqliteIndexStorage.addNode(data), true);
}
std::vector<Id> PersistentStorage::addNodes(const std::vector<StorageNode>& nodes)
{
return m_sqliteIndexStorage.addNodes(nodes);
} }
void PersistentStorage::addSymbol(const StorageSymbol& data) void PersistentStorage::addSymbol(const StorageSymbol& data)
@@ -56,6 +61,11 @@ void PersistentStorage::addSymbol(const StorageSymbol& data)
m_sqliteIndexStorage.addSymbol(data); m_sqliteIndexStorage.addSymbol(data);
} }
void PersistentStorage::addSymbols(const std::vector<StorageSymbol>& symbols)
{
m_sqliteIndexStorage.addSymbols(symbols);
}
void PersistentStorage::addFile(const StorageFile& data) void PersistentStorage::addFile(const StorageFile& data)
{ {
const StorageFile storedFile = m_sqliteIndexStorage.getFirstById<StorageFile>(data.id); const StorageFile storedFile = m_sqliteIndexStorage.getFirstById<StorageFile>(data.id);
@@ -80,17 +90,32 @@ void PersistentStorage::addFile(const StorageFile& data)
Id PersistentStorage::addEdge(const StorageEdgeData& data) Id PersistentStorage::addEdge(const StorageEdgeData& data)
{ {
return m_sqliteIndexStorage.addEdge(data).id; return m_sqliteIndexStorage.addEdge(data);
}
std::vector<Id> PersistentStorage::addEdges(const std::vector<StorageEdge>& edges)
{
return m_sqliteIndexStorage.addEdges(edges);
} }
Id PersistentStorage::addLocalSymbol(const StorageLocalSymbolData& data) Id PersistentStorage::addLocalSymbol(const StorageLocalSymbolData& data)
{ {
return m_sqliteIndexStorage.addLocalSymbol(data).id; return m_sqliteIndexStorage.addLocalSymbol(data);
}
std::vector<Id> PersistentStorage::addLocalSymbols(const std::set<StorageLocalSymbol>& symbols)
{
return m_sqliteIndexStorage.addLocalSymbols(symbols);
} }
Id PersistentStorage::addSourceLocation(const StorageSourceLocationData& data) Id PersistentStorage::addSourceLocation(const StorageSourceLocationData& data)
{ {
return m_sqliteIndexStorage.addSourceLocation(data).id; return m_sqliteIndexStorage.addSourceLocation(data);
}
std::vector<Id> PersistentStorage::addSourceLocations(const std::vector<StorageSourceLocation>& locations)
{
return m_sqliteIndexStorage.addSourceLocations(locations);
} }
void PersistentStorage::addOccurrence(const StorageOccurrence& data) void PersistentStorage::addOccurrence(const StorageOccurrence& data)
@@ -108,6 +133,11 @@ void PersistentStorage::addComponentAccess(const StorageComponentAccess& compone
m_sqliteIndexStorage.addComponentAccess(componentAccess); m_sqliteIndexStorage.addComponentAccess(componentAccess);
} }
void PersistentStorage::addComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses)
{
m_sqliteIndexStorage.addComponentAccesses(componentAccesses);
}
void PersistentStorage::addCommentLocation(const StorageCommentLocationData& data) void PersistentStorage::addCommentLocation(const StorageCommentLocationData& data)
{ {
m_sqliteIndexStorage.addCommentLocation(data); m_sqliteIndexStorage.addCommentLocation(data);
@@ -118,84 +148,64 @@ void PersistentStorage::addError(const StorageErrorData& data)
m_sqliteIndexStorage.addError(data); m_sqliteIndexStorage.addError(data);
} }
void PersistentStorage::forEachNode(std::function<void(const StorageNode& /*data*/)> callback) const const std::vector<StorageNode>& PersistentStorage::getStorageNodes() const
{ {
for (StorageNode& node: m_sqliteIndexStorage.getAll<StorageNode>()) return m_storageData.nodes = m_sqliteIndexStorage.getAll<StorageNode>();
{
callback(node);
}
} }
void PersistentStorage::forEachFile(std::function<void(const StorageFile& /*data*/)> callback) const const std::vector<StorageFile>& PersistentStorage::getStorageFiles() const
{ {
for (StorageFile& file: m_sqliteIndexStorage.getAll<StorageFile>()) return m_storageData.files = m_sqliteIndexStorage.getAll<StorageFile>();
{
callback(file);
}
} }
void PersistentStorage::forEachSymbol(std::function<void(const StorageSymbol& /*data*/)> callback) const const std::vector<StorageSymbol>& PersistentStorage::getStorageSymbols() const
{ {
for (StorageSymbol& symbol: m_sqliteIndexStorage.getAll<StorageSymbol>()) return m_storageData.symbols = m_sqliteIndexStorage.getAll<StorageSymbol>();
{
callback(symbol);
}
} }
void PersistentStorage::forEachEdge(std::function<void(const StorageEdge& /*data*/)> callback) const const std::vector<StorageEdge>& PersistentStorage::getStorageEdges() const
{ {
for (StorageEdge& edge: m_sqliteIndexStorage.getAll<StorageEdge>()) return m_storageData.edges = m_sqliteIndexStorage.getAll<StorageEdge>();
{
callback(edge);
}
} }
void PersistentStorage::forEachLocalSymbol(std::function<void(const StorageLocalSymbol& /*data*/)> callback) const const std::set<StorageLocalSymbol>& PersistentStorage::getStorageLocalSymbols() const
{ {
for (StorageLocalSymbol& localSymbol: m_sqliteIndexStorage.getAll<StorageLocalSymbol>()) return m_storageData.locals = utility::toSet(m_sqliteIndexStorage.getAll<StorageLocalSymbol>());
{
callback(localSymbol);
}
} }
void PersistentStorage::forEachSourceLocation(std::function<void(const StorageSourceLocation& /*data*/)> callback) const const std::set<StorageSourceLocation>& PersistentStorage::getStorageSourceLocations() const
{ {
for (StorageSourceLocation& sourceLocation: m_sqliteIndexStorage.getAll<StorageSourceLocation>()) return m_storageData.locations = utility::toSet(m_sqliteIndexStorage.getAll<StorageSourceLocation>());
{
callback(sourceLocation);
}
} }
void PersistentStorage::forEachOccurrence(std::function<void(const StorageOccurrence& /*data*/)> callback) const const std::set<StorageOccurrence>& PersistentStorage::getStorageOccurrences() const
{ {
for (StorageOccurrence& occurrence: m_sqliteIndexStorage.getAll<StorageOccurrence>()) return m_storageData.occurrences = utility::toSet(m_sqliteIndexStorage.getAll<StorageOccurrence>());
{
callback(occurrence);
}
} }
void PersistentStorage::forEachComponentAccess(std::function<void(const StorageComponentAccess& /*data*/)> callback) const const std::set<StorageComponentAccess>& PersistentStorage::getComponentAccesses() const
{ {
for (StorageComponentAccess& componentAccess: m_sqliteIndexStorage.getAll<StorageComponentAccess>()) return m_storageData.accesses = utility::toSet(m_sqliteIndexStorage.getAll<StorageComponentAccess>());
{
callback(componentAccess);
}
} }
void PersistentStorage::forEachCommentLocation(std::function<void(const StorageCommentLocationData& /*data*/)> callback) const const std::set<StorageCommentLocationData>& PersistentStorage::getCommentLocations() const
{ {
for (StorageCommentLocation& commentLocation: m_sqliteIndexStorage.getAll<StorageCommentLocation>()) std::set<StorageCommentLocationData> comments;
for (const StorageCommentLocation& comment : m_sqliteIndexStorage.getAll<StorageCommentLocation>())
{ {
callback(commentLocation); comments.emplace(comment);
} }
return m_storageData.comments = comments;
} }
void PersistentStorage::forEachError(std::function<void(const StorageErrorData& /*data*/)> callback) const const std::vector<StorageErrorData>& PersistentStorage::getErrors() const
{ {
for (StorageError& error: m_sqliteIndexStorage.getAll<StorageError>()) std::vector<StorageErrorData> errors;
for (const StorageError& error : m_sqliteIndexStorage.getAll<StorageError>())
{ {
callback(error); errors.emplace_back(error);
} }
return m_storageData.errors = errors;
} }
void PersistentStorage::startInjection() void PersistentStorage::startInjection()
+29 -10
View File
@@ -20,27 +20,33 @@ public:
PersistentStorage(const FilePath& dbPath, const FilePath& bookmarkPath); PersistentStorage(const FilePath& dbPath, const FilePath& bookmarkPath);
std::pair<Id, bool> addNode(const StorageNodeData& data) override; std::pair<Id, bool> addNode(const StorageNodeData& data) override;
std::vector<Id> addNodes(const std::vector<StorageNode>& nodes) override;
void addSymbol(const StorageSymbol& data) override; void addSymbol(const StorageSymbol& data) override;
void addSymbols(const std::vector<StorageSymbol>& symbols) override;
void addFile(const StorageFile& data) override; void addFile(const StorageFile& data) override;
Id addEdge(const StorageEdgeData& data) override; Id addEdge(const StorageEdgeData& data) override;
std::vector<Id> addEdges(const std::vector<StorageEdge>& edges) override;
Id addLocalSymbol(const StorageLocalSymbolData& data) override; Id addLocalSymbol(const StorageLocalSymbolData& data) override;
std::vector<Id> addLocalSymbols(const std::set<StorageLocalSymbol>& symbols) override;
Id addSourceLocation(const StorageSourceLocationData& data) override; Id addSourceLocation(const StorageSourceLocationData& data) override;
std::vector<Id> addSourceLocations(const std::vector<StorageSourceLocation>& locations) override;
void addOccurrence(const StorageOccurrence& data) override; void addOccurrence(const StorageOccurrence& data) override;
void addOccurrences(const std::vector<StorageOccurrence>& occurrences) override; void addOccurrences(const std::vector<StorageOccurrence>& occurrences) override;
void addComponentAccess(const StorageComponentAccess& componentAccess) override; void addComponentAccess(const StorageComponentAccess& componentAccess) override;
void addComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses) override;
void addCommentLocation(const StorageCommentLocationData& data) override; void addCommentLocation(const StorageCommentLocationData& data) override;
void addError(const StorageErrorData& data) override; void addError(const StorageErrorData& data) override;
void forEachNode(std::function<void(const StorageNode& /*data*/)> callback) const override; const std::vector<StorageNode>& getStorageNodes() const override;
void forEachFile(std::function<void(const StorageFile& /*data*/)> callback) const override; const std::vector<StorageFile>& getStorageFiles() const override;
void forEachSymbol(std::function<void(const StorageSymbol& /*data*/)> callback) const override; const std::vector<StorageSymbol>& getStorageSymbols() const override;
void forEachEdge(std::function<void(const StorageEdge& /*data*/)> callback) const override; const std::vector<StorageEdge>& getStorageEdges() const override;
void forEachLocalSymbol(std::function<void(const StorageLocalSymbol& /*data*/)> callback) const override; const std::set<StorageLocalSymbol>& getStorageLocalSymbols() const override;
void forEachSourceLocation(std::function<void(const StorageSourceLocation& /*data*/)> callback) const override; const std::set<StorageSourceLocation>& getStorageSourceLocations() const override;
void forEachOccurrence(std::function<void(const StorageOccurrence& /*data*/)> callback) const override; const std::set<StorageOccurrence>& getStorageOccurrences() const override;
void forEachComponentAccess(std::function<void(const StorageComponentAccess& /*data*/)> callback) const override; const std::set<StorageComponentAccess>& getComponentAccesses() const override;
void forEachCommentLocation(std::function<void(const StorageCommentLocationData& /*data*/)> callback) const override; const std::set<StorageCommentLocationData>& getCommentLocations() const override;
void forEachError(std::function<void(const StorageErrorData& /*data*/)> callback) const override; const std::vector<StorageErrorData>& getErrors() const override;
void startInjection() override; void startInjection() override;
void finishInjection() override; void finishInjection() override;
@@ -153,6 +159,19 @@ public:
const std::vector<Id>& locationIds, const std::vector<Id>& localSymbolIds) const override; const std::vector<Id>& locationIds, const std::vector<Id>& localSymbolIds) const override;
private: private:
mutable struct {
std::vector<StorageNode> nodes;
std::vector<StorageFile> files;
std::vector<StorageSymbol> symbols;
std::vector<StorageEdge> edges;
std::set<StorageLocalSymbol> locals;
std::set<StorageSourceLocation> locations;
std::set<StorageOccurrence> occurrences;
std::set<StorageComponentAccess> accesses;
std::set<StorageCommentLocationData> comments;
std::vector<StorageErrorData> errors;
} m_storageData;
Id getFileNodeId(const FilePath& filePath) const; Id getFileNodeId(const FilePath& filePath) const;
std::vector<Id> getFileNodeIds(const std::vector<FilePath>& filePaths) const; std::vector<Id> getFileNodeIds(const std::vector<FilePath>& filePaths) const;
std::set<Id> getFileNodeIds(const std::set<FilePath>& filePaths) const; std::set<Id> getFileNodeIds(const std::set<FilePath>& filePaths) const;
+193 -110
View File
@@ -2,6 +2,7 @@
#include <unordered_map> #include <unordered_map>
#include "logging.h"
#include "StorageCommentLocation.h" #include "StorageCommentLocation.h"
#include "StorageComponentAccess.h" #include "StorageComponentAccess.h"
#include "StorageEdge.h" #include "StorageEdge.h"
@@ -22,181 +23,263 @@ void Storage::inject(Storage* injected)
{ {
std::lock_guard<std::mutex> lock(m_dataMutex); std::lock_guard<std::mutex> lock(m_dataMutex);
std::map<Id, Id> injectedIdToOwnElementId;
std::map<Id, Id> injectedIdToOwnSourceLocationId;
TRACE(); TRACE();
startInjection(); startInjection();
injected->forEachError( {
[&](const StorageErrorData& injectedData) // TRACE("inject errors");
for (const StorageErrorData& error : injected->getErrors())
{ {
addError(injectedData); addError(error);
} }
); }
std::unordered_map<Id, Id> injectedIdToOwnElementId; {
// TRACE("inject nodes");
injected->forEachNode( const std::vector<StorageNode>& nodes = injected->getStorageNodes();
[&](const StorageNode& injectedData)
std::vector<Id> nodeIds = addNodes(nodes);
for (size_t i = 0; i < nodes.size(); i++)
{ {
const Id ownId = addNode(injectedData).first; if (nodeIds[i])
if (ownId != 0)
{ {
injectedIdToOwnElementId[injectedData.id] = ownId; injectedIdToOwnElementId.emplace(nodes[i].id, nodeIds[i]);
} }
} }
); }
injected->forEachFile( {
[&](const StorageFile& injectedData) // TRACE("inject files");
for (const StorageFile& file : injected->getStorageFiles())
{ {
std::unordered_map<Id, Id>::const_iterator it; auto it = injectedIdToOwnElementId.find(file.id);
it = injectedIdToOwnElementId.find(injectedData.id);
if (it != injectedIdToOwnElementId.end()) if (it != injectedIdToOwnElementId.end())
{ {
const Id ownId = it->second; addFile(StorageFile(
addFile(StorageFile(ownId, injectedData.filePath, injectedData.modificationTime, injectedData.indexed, injectedData.complete)); it->second,
file.filePath,
file.modificationTime,
file.indexed,
file.complete
));
} }
} }
); }
injected->forEachSymbol( {
[&](const StorageSymbol& injectedData) // TRACE("inject symbols");
std::vector<StorageSymbol> symbols = injected->getStorageSymbols();
for (size_t i = 0; i < symbols.size(); i++)
{ {
std::unordered_map<Id, Id>::const_iterator it; auto it = injectedIdToOwnElementId.find(symbols[i].id);
it = injectedIdToOwnElementId.find(injectedData.id);
if (it != injectedIdToOwnElementId.end()) if (it != injectedIdToOwnElementId.end())
{ {
const Id ownId = it->second; symbols[i].id = it->second;
addSymbol(StorageSymbol(ownId, injectedData.definitionKind)); }
else
{
LOG_WARNING("New symbol id could not be found.");
symbols.erase(symbols.begin() + i);
i--;
} }
} }
);
injected->forEachEdge( addSymbols(symbols);
[&](const StorageEdge& injectedData) }
{
// TRACE("inject edges");
std::vector<StorageEdge> edges = injected->getStorageEdges();
for (size_t i = 0; i < edges.size(); i++)
{ {
std::unordered_map<Id, Id>::const_iterator it; StorageEdge& edge = edges[i];
it = injectedIdToOwnElementId.find(injectedData.sourceNodeId); size_t updateCount = 0;
if (it == injectedIdToOwnElementId.end())
auto it = injectedIdToOwnElementId.find(edge.sourceNodeId);
if (it != injectedIdToOwnElementId.end())
{ {
return; edge.sourceNodeId = it->second;
updateCount++;
} }
const Id ownSourceId = it->second;
it = injectedIdToOwnElementId.find(injectedData.targetNodeId); it = injectedIdToOwnElementId.find(edge.targetNodeId);
if (it == injectedIdToOwnElementId.end()) if (it != injectedIdToOwnElementId.end())
{ {
return; edge.targetNodeId = it->second;
updateCount++;
} }
const Id ownTargetId = it->second;
const Id ownId = addEdge(StorageEdgeData(injectedData.type, ownSourceId, ownTargetId)); if (updateCount != 2)
if (ownId != 0)
{ {
injectedIdToOwnElementId[injectedData.id] = ownId; LOG_WARNING("New edge source or target id could not be found.");
edges.erase(edges.begin() + i);
i--;
} }
} }
);
injected->forEachLocalSymbol( std::vector<Id> edgeIds = addEdges(edges);
[&](const StorageLocalSymbol& injectedData)
if (edges.size() == edgeIds.size())
{ {
const Id ownId = addLocalSymbol(injectedData); for (size_t i = 0; i < edgeIds.size(); i++)
if (ownId != 0)
{ {
injectedIdToOwnElementId[injectedData.id] = ownId; if (edgeIds[i])
{
injectedIdToOwnElementId.emplace(edges[i].id, edgeIds[i]);
}
} }
} }
); else
std::unordered_map<Id, Id> injectedIdToOwnSourceLocationId;
injected->forEachSourceLocation(
[&](const StorageSourceLocation& injectedData)
{ {
std::unordered_map<Id, Id>::const_iterator it; LOG_ERROR("Returned edge ids don't match injected count.");
it = injectedIdToOwnElementId.find(injectedData.fileNodeId); }
}
{
// TRACE("inject local symbols");
const std::set<StorageLocalSymbol>& symbols = injected->getStorageLocalSymbols();
std::vector<Id> symbolIds = addLocalSymbols(symbols);
auto it = symbols.begin();
for (size_t i = 0; i < symbols.size(); i++)
{
if (symbolIds[i])
{
injectedIdToOwnElementId.emplace(it->id, symbolIds[i]);
}
it++;
}
}
{
// TRACE("inject locations");
const std::set<StorageSourceLocation>& oldLocations = injected->getStorageSourceLocations();
std::vector<StorageSourceLocation> locations;
locations.reserve(oldLocations.size());
for (const StorageSourceLocation& location : oldLocations)
{
auto it = injectedIdToOwnElementId.find(location.fileNodeId);
if (it != injectedIdToOwnElementId.end()) if (it != injectedIdToOwnElementId.end())
{ {
const Id ownFileNodeId = it->second; const Id ownFileNodeId = it->second;
locations.emplace_back(
const Id ownId = addSourceLocation(StorageSourceLocationData( location.id,
ownFileNodeId, ownFileNodeId,
injectedData.startLine, location.startLine,
injectedData.startCol, location.startCol,
injectedData.endLine, location.endLine,
injectedData.endCol, location.endCol,
injectedData.type location.type
)); );
if (ownId != 0) }
}
std::vector<Id> locationIds = addSourceLocations(locations);
if (locations.size() == locationIds.size())
{
for (size_t i = 0; i < locationIds.size(); i++)
{
if (locationIds[i])
{ {
injectedIdToOwnSourceLocationId[injectedData.id] = ownId; injectedIdToOwnSourceLocationId.emplace(locations[i].id, locationIds[i]);
} }
} }
} }
); else
{
LOG_ERROR("Returned source locations ids don't match injected count.");
}
}
{ {
// TRACE("inject occurrences");
const std::set<StorageOccurrence>& oldOccurences = injected->getStorageOccurrences();
std::vector<StorageOccurrence> occurrences; std::vector<StorageOccurrence> occurrences;
injected->forEachOccurrence( occurrences.reserve(oldOccurences.size());
[&](const StorageOccurrence& injectedData)
for (const StorageOccurrence& occurrence : oldOccurences)
{
Id elementId = 0;
Id sourceLocationId = 0;
auto it = injectedIdToOwnElementId.find(occurrence.elementId);
if (it != injectedIdToOwnElementId.end())
{ {
std::unordered_map<Id, Id>::const_iterator it; elementId = it->second;
it = injectedIdToOwnElementId.find(injectedData.elementId);
if (it == injectedIdToOwnElementId.end())
{
return;
}
const Id ownElementId = it->second;
it = injectedIdToOwnSourceLocationId.find(injectedData.sourceLocationId);
if (it == injectedIdToOwnSourceLocationId.end())
{
return;
}
const Id ownSourceLocationId = it->second;
occurrences.emplace_back(ownElementId, ownSourceLocationId);
} }
);
it = injectedIdToOwnSourceLocationId.find(occurrence.sourceLocationId);
if (it != injectedIdToOwnSourceLocationId.end())
{
sourceLocationId = it->second;
}
if (elementId && sourceLocationId)
{
occurrences.emplace_back(elementId, sourceLocationId);
}
else
{
LOG_WARNING("New occurrence element or location id could not be found.");
}
}
addOccurrences(occurrences); addOccurrences(occurrences);
} }
injected->forEachComponentAccess( {
[&](const StorageComponentAccess& injectedData) // TRACE("inject accesses");
const std::set<StorageComponentAccess>& oldAccesses = injected->getComponentAccesses();
std::vector<StorageComponentAccess> accesses;
accesses.reserve(oldAccesses.size());
for (const StorageComponentAccess& access : oldAccesses)
{ {
std::unordered_map<Id, Id>::const_iterator it; auto it = injectedIdToOwnElementId.find(access.nodeId);
it = injectedIdToOwnElementId.find(injectedData.nodeId); if (it != injectedIdToOwnElementId.end())
if (it == injectedIdToOwnElementId.end())
{ {
return; accesses.emplace_back(it->second, access.type);
} }
const Id ownNodeId = it->second;
addComponentAccess(StorageComponentAccess(ownNodeId, injectedData.type));
} }
);
injected->forEachCommentLocation( addComponentAccesses(accesses);
[&](const StorageCommentLocationData& injectedData) }
{
// TRACE("inject comments");
for (const StorageCommentLocationData& location : injected->getCommentLocations())
{ {
std::unordered_map<Id, Id>::const_iterator it; auto it = injectedIdToOwnElementId.find(location.fileNodeId);
it = injectedIdToOwnElementId.find(injectedData.fileNodeId); if (it != injectedIdToOwnElementId.end())
if (it == injectedIdToOwnElementId.end())
{ {
return; const Id ownFileNodeId = it->second;
addCommentLocation(StorageCommentLocationData(
ownFileNodeId,
location.startLine,
location.startCol,
location.endLine,
location.endCol
));
} }
const Id ownFileNodeId = it->second;
addCommentLocation(StorageCommentLocationData(
ownFileNodeId,
injectedData.startLine,
injectedData.startCol,
injectedData.endLine,
injectedData.endCol
));
} }
); }
finishInjection(); finishInjection();
} }
+17 -10
View File
@@ -3,6 +3,7 @@
#include <functional> #include <functional>
#include <mutex> #include <mutex>
#include <set>
#include <string> #include <string>
#include "StorageCommentLocation.h" #include "StorageCommentLocation.h"
@@ -24,27 +25,33 @@ public:
virtual ~Storage() = default; virtual ~Storage() = default;
virtual std::pair<Id, bool> addNode(const StorageNodeData& data) = 0; virtual std::pair<Id, bool> addNode(const StorageNodeData& data) = 0;
virtual std::vector<Id> addNodes(const std::vector<StorageNode>& nodes) = 0;
virtual void addSymbol(const StorageSymbol& data) = 0; virtual void addSymbol(const StorageSymbol& data) = 0;
virtual void addSymbols(const std::vector<StorageSymbol>& symbols) = 0;
virtual void addFile(const StorageFile& data) = 0; virtual void addFile(const StorageFile& data) = 0;
virtual Id addEdge(const StorageEdgeData& data) = 0; virtual Id addEdge(const StorageEdgeData& data) = 0;
virtual std::vector<Id> addEdges(const std::vector<StorageEdge>& edges) = 0;
virtual Id addLocalSymbol(const StorageLocalSymbolData& data) = 0; virtual Id addLocalSymbol(const StorageLocalSymbolData& data) = 0;
virtual std::vector<Id> addLocalSymbols(const std::set<StorageLocalSymbol>& symbols) = 0;
virtual Id addSourceLocation(const StorageSourceLocationData& data) = 0; virtual Id addSourceLocation(const StorageSourceLocationData& data) = 0;
virtual std::vector<Id> addSourceLocations(const std::vector<StorageSourceLocation>& locations) = 0;
virtual void addOccurrence(const StorageOccurrence& data) = 0; virtual void addOccurrence(const StorageOccurrence& data) = 0;
virtual void addOccurrences(const std::vector<StorageOccurrence>& occurrences) = 0; virtual void addOccurrences(const std::vector<StorageOccurrence>& occurrences) = 0;
virtual void addComponentAccess(const StorageComponentAccess& componentAccess) = 0; virtual void addComponentAccess(const StorageComponentAccess& componentAccess) = 0;
virtual void addComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses) = 0;
virtual void addCommentLocation(const StorageCommentLocationData& data) = 0; virtual void addCommentLocation(const StorageCommentLocationData& data) = 0;
virtual void addError(const StorageErrorData& data) = 0; virtual void addError(const StorageErrorData& data) = 0;
virtual void forEachNode(std::function<void(const StorageNode& /*data*/)> callback) const = 0; virtual const std::vector<StorageNode>& getStorageNodes() const = 0;
virtual void forEachFile(std::function<void(const StorageFile& /*data*/)> callback) const = 0; virtual const std::vector<StorageFile>& getStorageFiles() const = 0;
virtual void forEachSymbol(std::function<void(const StorageSymbol& /*data*/)> callback) const = 0; virtual const std::vector<StorageSymbol>& getStorageSymbols() const = 0;
virtual void forEachEdge(std::function<void(const StorageEdge& /*data*/)> callback) const = 0; virtual const std::vector<StorageEdge>& getStorageEdges() const = 0;
virtual void forEachLocalSymbol(std::function<void(const StorageLocalSymbol& /*data*/)> callback) const = 0; virtual const std::set<StorageLocalSymbol>& getStorageLocalSymbols() const = 0;
virtual void forEachSourceLocation(std::function<void(const StorageSourceLocation& /*data*/)> callback) const = 0; virtual const std::set<StorageSourceLocation>& getStorageSourceLocations() const = 0;
virtual void forEachOccurrence(std::function<void(const StorageOccurrence& /*data*/)> callback) const = 0; virtual const std::set<StorageOccurrence>& getStorageOccurrences() const = 0;
virtual void forEachComponentAccess(std::function<void(const StorageComponentAccess& /*data*/)> callback) const = 0; virtual const std::set<StorageComponentAccess>& getComponentAccesses() const = 0;
virtual void forEachCommentLocation(std::function<void(const StorageCommentLocationData& /*data*/)> callback) const = 0; virtual const std::set<StorageCommentLocationData>& getCommentLocations() const = 0;
virtual void forEachError(std::function<void(const StorageErrorData& /*data*/)> callback) const = 0; virtual const std::vector<StorageErrorData>& getErrors() const = 0;
void inject(Storage* injected); void inject(Storage* injected);
+244 -203
View File
@@ -1,5 +1,6 @@
#include "SqliteIndexStorage.h" #include "SqliteIndexStorage.h"
#include <sstream>
#include <unordered_map> #include <unordered_map>
#include "FileSystem.h" #include "FileSystem.h"
@@ -12,7 +13,6 @@
const size_t SqliteIndexStorage::s_storageVersion = 19; const size_t SqliteIndexStorage::s_storageVersion = 19;
namespace namespace
{ {
std::tuple<std::wstring, uint32_t, uint32_t> splitLocalSymbolName(const std::wstring& name) std::tuple<std::wstring, uint32_t, uint32_t> splitLocalSymbolName(const std::wstring& name)
@@ -87,7 +87,13 @@ void SqliteIndexStorage::setProjectSettingsText(std::string text)
insertOrUpdateMetaValue("project_settings", text); insertOrUpdateMetaValue("project_settings", text);
} }
StorageNode SqliteIndexStorage::addNode(const StorageNodeData& data) Id SqliteIndexStorage::addNode(const StorageNodeData& data)
{
std::vector<Id> ids = addNodes({ StorageNode(0, data) });
return ids.size() ? ids[0] : 0;
}
std::vector<Id> SqliteIndexStorage::addNodes(const std::vector<StorageNode>& nodes)
{ {
if (m_tempNodeNameIndex.empty() && m_tempWNodeNameIndex.empty()) if (m_tempNodeNameIndex.empty() && m_tempWNodeNameIndex.empty())
{ {
@@ -107,70 +113,78 @@ StorageNode SqliteIndexStorage::addNode(const StorageNodeData& data)
} }
} }
std::string name = utility::encodeToUtf8(data.serializedName); std::vector<Id> nodeIds(nodes.size(), 0);
std::vector<StorageNode> nodesToInsert;
for (size_t i = 0; i < nodes.size(); i++)
{ {
Id nodeId; const StorageNodeData& data = nodes[i];
if (name.size() != data.serializedName.size()) std::string name = utility::encodeToUtf8(data.serializedName);
{ {
nodeId = m_tempWNodeNameIndex.find(data.serializedName); Id nodeId;
} if (name.size() != data.serializedName.size())
else
{
nodeId = m_tempNodeNameIndex.find(name);
}
if (nodeId)
{
auto it = m_tempNodeTypes.find(nodeId);
if (it != m_tempNodeTypes.end() && it->second < data.type)
{ {
setNodeType(data.type, nodeId); nodeId = m_tempWNodeNameIndex.find(data.serializedName);
m_tempNodeTypes[nodeId] = data.type; }
else
{
nodeId = m_tempNodeNameIndex.find(name);
}
if (nodeId)
{
auto it = m_tempNodeTypes.find(nodeId);
if (it != m_tempNodeTypes.end() && it->second < data.type)
{
setNodeType(data.type, nodeId);
m_tempNodeTypes[nodeId] = data.type;
}
nodeIds[i] = nodeId;
}
else
{
executeStatement(m_insertElementStmt);
Id id = m_database.lastRowId();
nodesToInsert.emplace_back(id, data);
nodeIds[i] = id;
if (name.size() != data.serializedName.size())
{
m_tempWNodeNameIndex.add(data.serializedName, id);
}
else
{
m_tempNodeNameIndex.add(name, id);
}
m_tempNodeTypes.emplace(id, data.type);
} }
return StorageNode(nodeId, data);
} }
} }
Id id = 0; if (nodesToInsert.size())
{ {
executeStatement(m_insertElementStmt); m_insertNodeBatchStatement.execute(nodesToInsert, this);
id = m_database.lastRowId();
m_insertElementStmt.reset();
}
{
m_inserNodeStmt.bind(1, int(id));
m_inserNodeStmt.bind(2, data.type);
m_inserNodeStmt.bind(3, name.c_str());
executeStatement(m_inserNodeStmt);
m_inserNodeStmt.reset();
} }
if (name.size() != data.serializedName.size()) return nodeIds;
{
m_tempWNodeNameIndex.add(data.serializedName, id);
}
else
{
m_tempNodeNameIndex.add(name, id);
}
m_tempNodeTypes.emplace(id, data.type);
return StorageNode(id, data);
} }
void SqliteIndexStorage::addSymbol(const StorageSymbol& data) bool SqliteIndexStorage::addSymbol(const StorageSymbol& data)
{ {
m_insertSymbolStmt.bind(1, int(data.id)); return addSymbols({ data });
m_insertSymbolStmt.bind(2, data.definitionKind);
executeStatement(m_insertSymbolStmt);
m_insertSymbolStmt.reset();
} }
void SqliteIndexStorage::addFile(const StorageFile& data) bool SqliteIndexStorage::addSymbols(const std::vector<StorageSymbol>& symbols)
{
return m_insertSymbolBatchStatement.execute(symbols, this);
}
bool SqliteIndexStorage::addFile(const StorageFile& data)
{ {
if (getFileByPath(data.filePath).id != 0) if (getFileByPath(data.filePath).id != 0)
{ {
return; return false;
} }
FilePath filePath(data.filePath); FilePath filePath(data.filePath);
@@ -198,19 +212,25 @@ void SqliteIndexStorage::addFile(const StorageFile& data)
m_insertFileStmt.bind(5, data.complete); m_insertFileStmt.bind(5, data.complete);
m_insertFileStmt.bind(6, lineCount); m_insertFileStmt.bind(6, lineCount);
success = executeStatement(m_insertFileStmt); success = executeStatement(m_insertFileStmt);
m_insertFileStmt.reset();
} }
if (success && content) if (success && content)
{ {
m_insertFileContentStmt.bind(1, int(data.id)); m_insertFileContentStmt.bind(1, int(data.id));
m_insertFileContentStmt.bind(2, content->getText().c_str()); m_insertFileContentStmt.bind(2, content->getText().c_str());
executeStatement(m_insertFileContentStmt); success = executeStatement(m_insertFileContentStmt);
m_insertFileContentStmt.reset();
} }
return success;
} }
StorageEdge SqliteIndexStorage::addEdge(const StorageEdgeData& data) Id SqliteIndexStorage::addEdge(const StorageEdgeData& data)
{
std::vector<Id> ids = addEdges({ StorageEdge(0, data) });
return ids.size() ? ids[0] : 0;
}
std::vector<Id> SqliteIndexStorage::addEdges(const std::vector<StorageEdge>& edges)
{ {
if (m_tempEdgeIndex.empty()) if (m_tempEdgeIndex.empty())
{ {
@@ -220,35 +240,43 @@ StorageEdge SqliteIndexStorage::addEdge(const StorageEdgeData& data)
} }
} }
std::vector<Id> edgeIds(edges.size(), 0);
std::vector<StorageEdge> edgesToInsert;
for (size_t i = 0; i < edges.size(); i++)
{ {
const StorageEdge& data = edges[i];
std::map<StorageEdgeData, Id>::const_iterator it = m_tempEdgeIndex.find(data); std::map<StorageEdgeData, Id>::const_iterator it = m_tempEdgeIndex.find(data);
if (it != m_tempEdgeIndex.end()) if (it != m_tempEdgeIndex.end())
{ {
return StorageEdge(it->second, data); edgeIds[i] = it->second;
}
else
{
executeStatement(m_insertElementStmt);
Id id = m_database.lastRowId();
edgeIds[i] = id;
edgesToInsert.emplace_back(id, data);
m_tempEdgeIndex.emplace(data, id);
} }
} }
Id id = 0; if (edgesToInsert.size())
{ {
executeStatement(m_insertElementStmt); m_insertEdgeBatchStatement.execute(edgesToInsert, this);
id = m_database.lastRowId();
m_insertElementStmt.reset();
}
{
m_insertEdgeStmt.bind(1, int(id));
m_insertEdgeStmt.bind(2, data.type);
m_insertEdgeStmt.bind(3, int(data.sourceNodeId));
m_insertEdgeStmt.bind(4, int(data.targetNodeId));
executeStatement(m_insertEdgeStmt);
m_insertEdgeStmt.reset();
} }
m_tempEdgeIndex.emplace(data, id); return edgeIds;
return StorageEdge(id, data);
} }
StorageLocalSymbol SqliteIndexStorage::addLocalSymbol(const StorageLocalSymbolData& data) Id SqliteIndexStorage::addLocalSymbol(const StorageLocalSymbolData& data)
{
std::vector<Id> ids = addLocalSymbols({ StorageLocalSymbol(0, data) });
return ids.size() ? ids[0] : 0;
}
std::vector<Id> SqliteIndexStorage::addLocalSymbols(const std::set<StorageLocalSymbol>& symbols)
{ {
std::wstring name; std::wstring name;
uint32_t line; uint32_t line;
@@ -266,42 +294,55 @@ StorageLocalSymbol SqliteIndexStorage::addLocalSymbol(const StorageLocalSymbolDa
} }
} }
std::tie(name, line, col) = splitLocalSymbolName(data.name); std::vector<Id> symbolIds(symbols.size(), 0);
if (name.size()) std::vector<StorageLocalSymbol> symbolsToInsert;
auto it = symbols.begin();
for (size_t i = 0; i < symbols.size(); i++)
{ {
auto it = m_tempLocalSymbolIndex.find(name); const StorageLocalSymbol& data = *it;
if (it != m_tempLocalSymbolIndex.end()) std::tie(name, line, col) = splitLocalSymbolName(data.name);
if (name.size())
{ {
auto it2 = it->second.find(std::make_pair(line, col)); auto it = m_tempLocalSymbolIndex.find(name);
if (it2 != it->second.end()) if (it != m_tempLocalSymbolIndex.end())
{ {
return StorageLocalSymbol(it2->second, data); auto it2 = it->second.find(std::make_pair(line, col));
if (it2 != it->second.end())
{
symbolIds[i] = it2->second;
}
} }
} }
if (!symbolIds[i])
{
executeStatement(m_insertElementStmt);
Id id = m_database.lastRowId();
symbolIds[i] = id;
symbolsToInsert.emplace_back(id, data);
m_tempLocalSymbolIndex[name].emplace(std::make_pair(line, col), id);
}
it++;
} }
Id id = 0; if (symbolsToInsert.size())
{ {
executeStatement(m_insertElementStmt); m_insertLocalSymbolBatchStatement.execute(symbolsToInsert, this);
id = m_database.lastRowId();
m_insertElementStmt.reset();
}
{
m_inserLocalSymbolStmt.bind(1, int(id));
m_inserLocalSymbolStmt.bind(2, utility::encodeToUtf8(data.name).c_str());
executeStatement(m_inserLocalSymbolStmt);
m_inserLocalSymbolStmt.reset();
} }
if (name.size()) return symbolIds;
{
m_tempLocalSymbolIndex[name].emplace(std::make_pair(line, col), id);
}
return StorageLocalSymbol(id, data);
} }
StorageSourceLocation SqliteIndexStorage::addSourceLocation(const StorageSourceLocationData& data) Id SqliteIndexStorage::addSourceLocation(const StorageSourceLocationData& data)
{
std::vector<Id> ids = addSourceLocations({ StorageSourceLocation(0, data) });
return ids.size() ? ids[0] : 0;
}
std::vector<Id> SqliteIndexStorage::addSourceLocations(const std::vector<StorageSourceLocation>& locations)
{ {
if (m_tempSourceLocationIndices.empty()) if (m_tempSourceLocationIndices.empty())
{ {
@@ -314,98 +355,59 @@ StorageSourceLocation SqliteIndexStorage::addSourceLocation(const StorageSourceL
} }
} }
const TempSourceLocation tempLoc(data.startLine, data.endLine - data.startLine, data.startCol, data.endCol, data.type); std::vector<Id> locationIds(locations.size(), 0);
std::vector<StorageSourceLocationData> locationsToInsert;
size_t lastRowId = executeStatementScalar("SELECT MAX(rowid) from source_location", 0);
std::map<TempSourceLocation, Id>& index = m_tempSourceLocationIndices[data.fileNodeId]; for (size_t i = 0; i < locations.size(); i++)
{ {
const StorageSourceLocation& data = locations[i];
const TempSourceLocation tempLoc(data.startLine, data.endLine - data.startLine, data.startCol, data.endCol, data.type);
std::map<TempSourceLocation, Id>& index = m_tempSourceLocationIndices[data.fileNodeId];
std::map<TempSourceLocation, Id>::const_iterator it = index.find(tempLoc); std::map<TempSourceLocation, Id>::const_iterator it = index.find(tempLoc);
if (it != index.end()) if (it != index.end())
{ {
return StorageSourceLocation(it->second, data); locationIds[i] = it->second;
}
else
{
executeStatement(m_insertElementStmt);
Id id = lastRowId + 1 + locationsToInsert.size();
locationIds[i] = id;
index.emplace(tempLoc, id);
locationsToInsert.emplace_back(data);
} }
} }
Id id = 0; if (locationsToInsert.size())
m_insertSourceLocationStmt.bind(1, int(data.fileNodeId));
m_insertSourceLocationStmt.bind(2, int(data.startLine));
m_insertSourceLocationStmt.bind(3, int(data.startCol));
m_insertSourceLocationStmt.bind(4, int(data.endLine));
m_insertSourceLocationStmt.bind(5, int(data.endCol));
m_insertSourceLocationStmt.bind(6, data.type);
const bool success = executeStatement(m_insertSourceLocationStmt);
if (success)
{ {
id = m_database.lastRowId(); m_insertSourceLocationBatchStatement.execute(locationsToInsert, this);
index.emplace(tempLoc, id);
} }
m_insertSourceLocationStmt.reset(); return locationIds;
return StorageSourceLocation(id, data);
} }
bool SqliteIndexStorage::addOccurrence(const StorageOccurrence& data) bool SqliteIndexStorage::addOccurrence(const StorageOccurrence& data)
{ {
m_insertOccurrenceStmt.bind(1, int(data.elementId)); return addOccurrences({ data });
m_insertOccurrenceStmt.bind(2, int(data.sourceLocationId));
const bool success = executeStatement(m_insertOccurrenceStmt);
m_insertOccurrenceStmt.reset();
return success;
} }
bool SqliteIndexStorage::addOccurrences(const std::vector<StorageOccurrence>& occurrences) bool SqliteIndexStorage::addOccurrences(const std::vector<StorageOccurrence>& occurrences)
{ {
size_t i = 0; return m_insertOccurenceBatchStatement.execute(occurrences, this);
while (occurrences.size() - i >= 100)
{
for (size_t j = 0; j < 100; j++)
{
m_insert100OccurrencesStmt.bind((j * 2) + 1, int(occurrences[i + j].elementId));
m_insert100OccurrencesStmt.bind((j * 2) + 2, int(occurrences[i + j].sourceLocationId));
}
const bool success = executeStatement(m_insert100OccurrencesStmt);
m_insert100OccurrencesStmt.reset();
if (!success)
{
return false;
}
i += 100;
}
if (i < occurrences.size())
{
std::string stmt = "INSERT OR IGNORE INTO occurrence(element_id, source_location_id) VALUES";
{
bool isFirst = true;
while (i < occurrences.size())
{
if (!isFirst)
{
stmt += ",";
}
isFirst = false;
stmt += "(" + std::to_string(occurrences[i].elementId) + "," + std::to_string(occurrences[i].sourceLocationId) + ")";
i++;
}
stmt += ";";
}
return executeStatement(stmt);
}
return true;
} }
bool SqliteIndexStorage::addComponentAccess(const StorageComponentAccess& componentAccess) bool SqliteIndexStorage::addComponentAccess(const StorageComponentAccess& componentAccess)
{ {
m_insertComponentAccessStmt.bind(1, int(componentAccess.nodeId)); return addComponentAccesses({ componentAccess });
m_insertComponentAccessStmt.bind(2, componentAccess.type); }
const bool success = executeStatement(m_insertComponentAccessStmt);
m_insertComponentAccessStmt.reset(); bool SqliteIndexStorage::addComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses)
return success; {
return m_insertComponentAccessBatchStatement.execute(componentAccesses, this);
} }
StorageCommentLocation SqliteIndexStorage::addCommentLocation(const StorageCommentLocationData& data) StorageCommentLocation SqliteIndexStorage::addCommentLocation(const StorageCommentLocationData& data)
@@ -423,7 +425,6 @@ StorageCommentLocation SqliteIndexStorage::addCommentLocation(const StorageComme
{ {
id = checkQuery.getIntField(0, 0); id = checkQuery.getIntField(0, 0);
} }
m_checkCommentLocationExistsStmt.reset(); m_checkCommentLocationExistsStmt.reset();
} }
@@ -440,8 +441,6 @@ StorageCommentLocation SqliteIndexStorage::addCommentLocation(const StorageComme
{ {
id = m_database.lastRowId(); id = m_database.lastRowId();
} }
m_insertCommentLocationStmt.reset();
} }
return StorageCommentLocation(id, data); return StorageCommentLocation(id, data);
@@ -464,7 +463,6 @@ StorageError SqliteIndexStorage::addError(const StorageErrorData& data)
{ {
id = checkQuery.getIntField(0, -1); id = checkQuery.getIntField(0, -1);
} }
m_checkErrorExistsStmt.reset(); m_checkErrorExistsStmt.reset();
} }
@@ -483,8 +481,6 @@ StorageError SqliteIndexStorage::addError(const StorageErrorData& data)
{ {
id = m_database.lastRowId(); id = m_database.lastRowId();
} }
m_insertErrorStmt.reset();
} }
return StorageError(id, data); return StorageError(id, data);
@@ -787,6 +783,8 @@ StorageNode SqliteIndexStorage::getNodeBySerializedName(const std::wstring& seri
} }
} }
stmt.reset();
return StorageNode(); return StorageNode();
} }
@@ -1252,50 +1250,93 @@ void SqliteIndexStorage::setupPrecompiledStatements()
{ {
try try
{ {
m_insertNodeBatchStatement.compile(
"INSERT INTO node(id, type, serialized_name) VALUES",
3,
[](CppSQLite3Statement& stmt, const StorageNode& node, size_t index)
{
stmt.bind(index * 3 + 1, int(node.id));
stmt.bind(index * 3 + 2, int(node.type));
stmt.bind(index * 3 + 3, utility::encodeToUtf8(node.serializedName).c_str());
},
m_database
);
m_insertEdgeBatchStatement.compile(
"INSERT INTO edge(id, type, source_node_id, target_node_id) VALUES",
4,
[](CppSQLite3Statement& stmt, const StorageEdge& edge, size_t index)
{
stmt.bind(index * 4 + 1, int(edge.id));
stmt.bind(index * 4 + 2, int(edge.type));
stmt.bind(index * 4 + 3, int(edge.sourceNodeId));
stmt.bind(index * 4 + 4, int(edge.targetNodeId));
},
m_database
);
m_insertSymbolBatchStatement.compile(
"INSERT OR IGNORE INTO symbol(id, definition_kind) VALUES",
2,
[](CppSQLite3Statement& stmt, const StorageSymbol& symbol, size_t index)
{
stmt.bind(index * 2 + 1, int(symbol.id));
stmt.bind(index * 2 + 2, int(symbol.definitionKind));
},
m_database
);
m_insertLocalSymbolBatchStatement.compile(
"INSERT INTO local_symbol(id, name) VALUES",
2,
[](CppSQLite3Statement& stmt, const StorageLocalSymbol& symbol, size_t index)
{
stmt.bind(index * 2 + 1, int(symbol.id));
stmt.bind(index * 2 + 2, utility::encodeToUtf8(symbol.name).c_str());
},
m_database
);
m_insertSourceLocationBatchStatement.compile(
"INSERT INTO source_location(file_node_id, start_line, start_column, end_line, end_column, type) VALUES",
6,
[](CppSQLite3Statement& stmt, const StorageSourceLocationData& location, size_t index)
{
stmt.bind(index * 6 + 1, int(location.fileNodeId));
stmt.bind(index * 6 + 2, int(location.startLine));
stmt.bind(index * 6 + 3, int(location.startCol));
stmt.bind(index * 6 + 4, int(location.endLine));
stmt.bind(index * 6 + 5, int(location.endCol));
stmt.bind(index * 6 + 6, int(location.type));
},
m_database
);
m_insertOccurenceBatchStatement.compile(
"INSERT OR IGNORE INTO occurrence(element_id, source_location_id) VALUES",
2,
[](CppSQLite3Statement& stmt, const StorageOccurrence& occurrence, size_t index)
{
stmt.bind(index * 2 + 1, int(occurrence.elementId));
stmt.bind(index * 2 + 2, int(occurrence.sourceLocationId));
},
m_database
);
m_insertComponentAccessBatchStatement.compile(
"INSERT OR IGNORE INTO component_access(node_id, type) VALUES",
2,
[](CppSQLite3Statement& stmt, const StorageComponentAccess& componentAccess, size_t index)
{
stmt.bind(index * 2 + 1, int(componentAccess.nodeId));
stmt.bind(index * 2 + 2, int(componentAccess.type));
},
m_database
);
m_insertElementStmt = m_database.compileStatement( m_insertElementStmt = m_database.compileStatement(
"INSERT INTO element(id) VALUES(NULL);" "INSERT INTO element(id) VALUES(NULL);"
); );
m_insertEdgeStmt = m_database.compileStatement(
"INSERT INTO edge(id, type, source_node_id, target_node_id) VALUES(?, ?, ?, ?);"
);
m_inserNodeStmt = m_database.compileStatement(
"INSERT INTO node(id, type, serialized_name) VALUES(?, ?, ?);"
);
m_insertSymbolStmt = m_database.compileStatement(
"INSERT OR IGNORE INTO symbol(id, definition_kind) VALUES(?, ?);"
);
m_insertFileStmt = m_database.compileStatement( m_insertFileStmt = m_database.compileStatement(
"INSERT INTO file(id, path, modification_time, indexed, complete, line_count) VALUES(?, ?, ?, ?, ?, ?);" "INSERT INTO file(id, path, modification_time, indexed, complete, line_count) VALUES(?, ?, ?, ?, ?, ?);"
); );
m_insertFileContentStmt = m_database.compileStatement( m_insertFileContentStmt = m_database.compileStatement(
"INSERT INTO filecontent(id, content) VALUES(?, ?);" "INSERT INTO filecontent(id, content) VALUES(?, ?);"
); );
m_inserLocalSymbolStmt = m_database.compileStatement(
"INSERT INTO local_symbol(id, name) VALUES(?, ?);"
);
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_insertOccurrenceStmt = m_database.compileStatement(
"INSERT OR IGNORE INTO occurrence(element_id, source_location_id) VALUES(?, ?);"
);
{
std::string stmt = "INSERT OR IGNORE INTO occurrence(element_id, source_location_id) VALUES";
for (int i = 0; i < 100; i++)
{
if (i != 0)
{
stmt += ",";
}
stmt += "(?, ?)";
}
stmt += ";";
m_insert100OccurrencesStmt = m_database.compileStatement(stmt.c_str());
}
m_insertComponentAccessStmt = m_database.compileStatement(
"INSERT OR IGNORE INTO component_access(node_id, type) VALUES(?, ?);"
);
m_checkCommentLocationExistsStmt = m_database.compileStatement( m_checkCommentLocationExistsStmt = m_database.compileStatement(
"SELECT id FROM comment_location WHERE " "SELECT id FROM comment_location WHERE "
"file_node_id = ? AND " "file_node_id = ? AND "
@@ -49,15 +49,21 @@ public:
std::string getProjectSettingsText() const; std::string getProjectSettingsText() const;
void setProjectSettingsText(std::string text); void setProjectSettingsText(std::string text);
StorageNode addNode(const StorageNodeData& data); Id addNode(const StorageNodeData& data);
void addSymbol(const StorageSymbol& data); std::vector<Id> addNodes(const std::vector<StorageNode>& nodes);
void addFile(const StorageFile& data); bool addSymbol(const StorageSymbol& data);
StorageEdge addEdge(const StorageEdgeData& data); bool addSymbols(const std::vector<StorageSymbol>& symbols);
StorageLocalSymbol addLocalSymbol(const StorageLocalSymbolData& data); bool addFile(const StorageFile& data);
StorageSourceLocation addSourceLocation(const StorageSourceLocationData& data); Id addEdge(const StorageEdgeData& data);
std::vector<Id> addEdges(const std::vector<StorageEdge>& edges);
Id addLocalSymbol(const StorageLocalSymbolData& data);
std::vector<Id> addLocalSymbols(const std::set<StorageLocalSymbol>& symbols);
Id addSourceLocation(const StorageSourceLocationData& data);
std::vector<Id> addSourceLocations(const std::vector<StorageSourceLocation>& locations);
bool addOccurrence(const StorageOccurrence& data); bool addOccurrence(const StorageOccurrence& data);
bool addOccurrences(const std::vector<StorageOccurrence>& occurrences); bool addOccurrences(const std::vector<StorageOccurrence>& occurrences);
bool addComponentAccess(const StorageComponentAccess& componentAccess); bool addComponentAccess(const StorageComponentAccess& componentAccess);
bool addComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses);
StorageCommentLocation addCommentLocation(const StorageCommentLocationData& data); StorageCommentLocation addCommentLocation(const StorageCommentLocationData& data);
StorageError addError(const StorageErrorData& data); StorageError addError(const StorageErrorData& data);
@@ -223,23 +229,92 @@ private:
std::map<std::wstring, std::map<std::pair<uint32_t, uint32_t>, Id>> m_tempLocalSymbolIndex; std::map<std::wstring, std::map<std::pair<uint32_t, uint32_t>, Id>> m_tempLocalSymbolIndex;
std::map<Id, std::map<TempSourceLocation, Id>> m_tempSourceLocationIndices; std::map<Id, std::map<TempSourceLocation, Id>> m_tempSourceLocationIndices;
template <typename StorageType>
class InsertBatchStatement
{
public:
void compile(
const std::string header,
size_t valueCount,
std::function<void(CppSQLite3Statement& stmt, const StorageType&, size_t)> bindValuesFunc,
CppSQLite3DB& database)
{
m_bindValuesFunc = bindValuesFunc;
std::string valueStr = '(' + utility::join(std::vector<std::string>(valueCount, "?"), ',') + ')';
for (size_t j = 0; j < 4; j++)
{
std::stringstream stmt;
stmt << header;
for (size_t i = 0; i < BATCH_SIZES[j]; i++)
{
if (i != 0)
{
stmt << ',';
}
stmt << valueStr;
}
stmt << ';';
m_stmt[j] = database.compileStatement(stmt.str().c_str());
}
}
bool execute(const std::vector<StorageType>& types, SqliteIndexStorage* storage)
{
size_t i = 0;
for (size_t x = 0; x < 4; x++)
{
while (types.size() - i >= BATCH_SIZES[x])
{
for (size_t j = 0; j < BATCH_SIZES[x]; j++)
{
m_bindValuesFunc(m_stmt[x], types[i + j], j);
}
const bool success = storage->executeStatement(m_stmt[x]);
if (!success)
{
return false;
}
i += BATCH_SIZES[x];
}
}
return true;
}
private:
static const size_t BATCH_SIZES[4];
CppSQLite3Statement m_stmt[4];
std::function<void(CppSQLite3Statement& stmt, const StorageType&, size_t)> m_bindValuesFunc;
};
InsertBatchStatement<StorageNode> m_insertNodeBatchStatement;
InsertBatchStatement<StorageEdge> m_insertEdgeBatchStatement;
InsertBatchStatement<StorageSymbol> m_insertSymbolBatchStatement;
InsertBatchStatement<StorageLocalSymbol> m_insertLocalSymbolBatchStatement;
InsertBatchStatement<StorageSourceLocationData> m_insertSourceLocationBatchStatement;
InsertBatchStatement<StorageOccurrence> m_insertOccurenceBatchStatement;
InsertBatchStatement<StorageComponentAccess> m_insertComponentAccessBatchStatement;
CppSQLite3Statement m_insertElementStmt; CppSQLite3Statement m_insertElementStmt;
CppSQLite3Statement m_insertEdgeStmt;
CppSQLite3Statement m_inserNodeStmt;
CppSQLite3Statement m_insertSymbolStmt;
CppSQLite3Statement m_insertFileStmt; CppSQLite3Statement m_insertFileStmt;
CppSQLite3Statement m_insertFileContentStmt; CppSQLite3Statement m_insertFileContentStmt;
CppSQLite3Statement m_inserLocalSymbolStmt;
CppSQLite3Statement m_insertSourceLocationStmt;
CppSQLite3Statement m_insertOccurrenceStmt;
CppSQLite3Statement m_insert100OccurrencesStmt;
CppSQLite3Statement m_insertComponentAccessStmt;
CppSQLite3Statement m_checkCommentLocationExistsStmt; CppSQLite3Statement m_checkCommentLocationExistsStmt;
CppSQLite3Statement m_insertCommentLocationStmt; CppSQLite3Statement m_insertCommentLocationStmt;
CppSQLite3Statement m_checkErrorExistsStmt; CppSQLite3Statement m_checkErrorExistsStmt;
CppSQLite3Statement m_insertErrorStmt; CppSQLite3Statement m_insertErrorStmt;
}; };
template<typename StorageType>
const size_t SqliteIndexStorage::InsertBatchStatement<StorageType>::BATCH_SIZES[4] = { 100, 27, 8, 1 };
template <> template <>
std::vector<StorageEdge> SqliteIndexStorage::doGetAll<StorageEdge>(const std::string& query) const; std::vector<StorageEdge> SqliteIndexStorage::doGetAll<StorageEdge>(const std::string& query) const;
template <> template <>
@@ -182,6 +182,8 @@ bool SqliteStorage::executeStatement(CppSQLite3Statement& statement) const
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage()); LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
return false; return false;
} }
statement.reset();
return true; return true;
} }
@@ -222,6 +224,7 @@ int SqliteStorage::executeStatementScalar(CppSQLite3Statement& statement, const
{ {
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage()); LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
} }
return ret; return ret;
} }
+6 -6
View File
@@ -32,7 +32,7 @@ public:
SqliteIndexStorage storage(databasePath); SqliteIndexStorage storage(databasePath);
storage.setup(); storage.setup();
storage.beginTransaction(); storage.beginTransaction();
int nodeId = storage.addNode(StorageNodeData(0, L"a")).id; int nodeId = storage.addNode(StorageNodeData(0, L"a"));
storage.removeElement(nodeId); storage.removeElement(nodeId);
storage.commitTransaction(); storage.commitTransaction();
nodeCount = storage.getNodeCount(); nodeCount = storage.getNodeCount();
@@ -50,8 +50,8 @@ public:
SqliteIndexStorage storage(databasePath); SqliteIndexStorage storage(databasePath);
storage.setup(); storage.setup();
storage.beginTransaction(); storage.beginTransaction();
int sourceNodeId = storage.addNode(StorageNodeData(0, L"a")).id; int sourceNodeId = storage.addNode(StorageNodeData(0, L"a"));
int targetNodeId = storage.addNode(StorageNodeData(0, L"b")).id; int targetNodeId = storage.addNode(StorageNodeData(0, L"b"));
storage.addEdge(StorageEdgeData(0, sourceNodeId, targetNodeId)); storage.addEdge(StorageEdgeData(0, sourceNodeId, targetNodeId));
storage.commitTransaction(); storage.commitTransaction();
edgeCount = storage.getEdgeCount(); edgeCount = storage.getEdgeCount();
@@ -69,9 +69,9 @@ public:
SqliteIndexStorage storage(databasePath); SqliteIndexStorage storage(databasePath);
storage.setup(); storage.setup();
storage.beginTransaction(); storage.beginTransaction();
int sourceNodeId = storage.addNode(StorageNodeData(0, L"a")).id; int sourceNodeId = storage.addNode(StorageNodeData(0, L"a"));
int targetNodeId = storage.addNode(StorageNodeData(0, L"b")).id; int targetNodeId = storage.addNode(StorageNodeData(0, L"b"));
int edgeId = storage.addEdge(StorageEdgeData(0, sourceNodeId, targetNodeId)).id; int edgeId = storage.addEdge(StorageEdgeData(0, sourceNodeId, targetNodeId));
storage.removeElement(edgeId); storage.removeElement(edgeId);
storage.commitTransaction(); storage.commitTransaction();
edgeCount = storage.getEdgeCount(); edgeCount = storage.getEdgeCount();
+5 -6
View File
@@ -69,14 +69,13 @@ public:
const Id sourceId = storage.getNodeIdForNameHierarchy(a); const Id sourceId = storage.getNodeIdForNameHierarchy(a);
const Id targetId = storage.getNodeIdForNameHierarchy(b); const Id targetId = storage.getNodeIdForNameHierarchy(b);
storage.forEachEdge([&](const StorageEdge& edge) for (auto edge : storage.getStorageEdges())
{
if (edge.sourceNodeId == sourceId && edge.targetNodeId == targetId && edge.type == Edge::typeToInt(Edge::EDGE_MEMBER))
{ {
if (edge.sourceNodeId == sourceId && edge.targetNodeId == targetId && edge.type == Edge::typeToInt(Edge::EDGE_MEMBER)) foundEdge = true;
{
foundEdge = true;
}
} }
); }
TS_ASSERT(foundEdge); TS_ASSERT(foundEdge);
} }