src: Improved project loading performance
* faster hierarchy cache building * cache symbol definition kinds * don't request files when caches can be used * save SearchEdge by starting character in SearchNode to avoid iteration when adding to SearchIndex * fixed disabled state of some search buttons
This commit is contained in:
@@ -47,7 +47,7 @@ QAbstractItemView#search_box_popup {
|
|||||||
background: <color:search/button/normal>;
|
background: <color:search/button/normal>;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
background-position: 15px 5px;
|
height: 30px;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +56,10 @@ QAbstractItemView#search_box_popup {
|
|||||||
border-top-left-radius: 0px;
|
border-top-left-radius: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#search_button:disabled, #home_button:disabled {
|
||||||
|
background: <color:search/button/disabled>;
|
||||||
|
}
|
||||||
|
|
||||||
#search_button:hover, #home_button:hover {
|
#search_button:hover, #home_button:hover {
|
||||||
background: <color:search/button/hover>;
|
background: <color:search/button/hover>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ void ActivationController::handleMessage(MessageActivateEdge* message)
|
|||||||
m.tokenIds = message->aggregationIds;
|
m.tokenIds = message->aggregationIds;
|
||||||
m.setKeepContent(false);
|
m.setKeepContent(false);
|
||||||
m.isAggregation = true;
|
m.isAggregation = true;
|
||||||
m.tokenNames.push_back(NameHierarchy(message->getFullName(), message->sourceNameHierarchy.getDelimiterrr()));
|
m.tokenNames.push_back(NameHierarchy(message->getFullName(), message->sourceNameHierarchy.getDelimiter()));
|
||||||
m.dispatchImmediately();
|
m.dispatchImmediately();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -42,7 +42,7 @@ void ActivationController::handleMessage(MessageActivateEdge* message)
|
|||||||
MessageActivateTokens m(message);
|
MessageActivateTokens m(message);
|
||||||
m.tokenIds.push_back(message->tokenId);
|
m.tokenIds.push_back(message->tokenId);
|
||||||
m.isEdge = true;
|
m.isEdge = true;
|
||||||
m.tokenNames.push_back(NameHierarchy(message->getFullName(), message->sourceNameHierarchy.getDelimiterrr()));
|
m.tokenNames.push_back(NameHierarchy(message->getFullName(), message->sourceNameHierarchy.getDelimiter()));
|
||||||
m.dispatchImmediately();
|
m.dispatchImmediately();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+110
-124
@@ -473,9 +473,12 @@ void PersistentStorage::clearCaches()
|
|||||||
{
|
{
|
||||||
m_symbolIndex.clear();
|
m_symbolIndex.clear();
|
||||||
m_fileIndex.clear();
|
m_fileIndex.clear();
|
||||||
|
|
||||||
m_fileNodeIds.clear();
|
m_fileNodeIds.clear();
|
||||||
m_fileNodePaths.clear();
|
m_fileNodePaths.clear();
|
||||||
m_fileNodeComplete.clear();
|
m_fileNodeComplete.clear();
|
||||||
|
m_symbolDefinitionKinds.clear();
|
||||||
|
|
||||||
m_hierarchyCache.clear();
|
m_hierarchyCache.clear();
|
||||||
m_fullTextSearchIndex.clear();
|
m_fullTextSearchIndex.clear();
|
||||||
}
|
}
|
||||||
@@ -600,6 +603,8 @@ NameHierarchy PersistentStorage::getNameHierarchyForNodeId(Id nodeId) const
|
|||||||
|
|
||||||
std::vector<NameHierarchy> PersistentStorage::getNameHierarchiesForNodeIds(const std::vector<Id> nodeIds) const
|
std::vector<NameHierarchy> PersistentStorage::getNameHierarchiesForNodeIds(const std::vector<Id> nodeIds) const
|
||||||
{
|
{
|
||||||
|
TRACE();
|
||||||
|
|
||||||
std::vector<NameHierarchy> nameHierarchies;
|
std::vector<NameHierarchy> nameHierarchies;
|
||||||
for (const StorageNode& storageNode : m_sqliteIndexStorage.getAllByIds<StorageNode>(nodeIds))
|
for (const StorageNode& storageNode : m_sqliteIndexStorage.getAllByIds<StorageNode>(nodeIds))
|
||||||
{
|
{
|
||||||
@@ -820,7 +825,7 @@ std::vector<SearchMatch> PersistentStorage::getAutocompletionSymbolMatches(
|
|||||||
match.text = name.getRange(idx, name.size()).getQualifiedName();
|
match.text = name.getRange(idx, name.size()).getQualifiedName();
|
||||||
match.subtext = name.getRange(0, idx).getQualifiedName();
|
match.subtext = name.getRange(0, idx).getQualifiedName();
|
||||||
|
|
||||||
match.delimiter = name.getDelimiterrr();
|
match.delimiter = name.getDelimiter();
|
||||||
|
|
||||||
match.indices = result.indices;
|
match.indices = result.indices;
|
||||||
match.score = result.score;
|
match.score = result.score;
|
||||||
@@ -903,6 +908,8 @@ std::vector<SearchMatch> PersistentStorage::getAutocompletionCommandMatches(cons
|
|||||||
|
|
||||||
std::vector<SearchMatch> PersistentStorage::getSearchMatchesForTokenIds(const std::vector<Id>& elementIds) const
|
std::vector<SearchMatch> PersistentStorage::getSearchMatchesForTokenIds(const std::vector<Id>& elementIds) const
|
||||||
{
|
{
|
||||||
|
TRACE();
|
||||||
|
|
||||||
// todo: what if all these elements share the same node in the searchindex?
|
// todo: what if all these elements share the same node in the searchindex?
|
||||||
// In that case there should be only one search match.
|
// In that case there should be only one search match.
|
||||||
std::vector<SearchMatch> matches;
|
std::vector<SearchMatch> matches;
|
||||||
@@ -932,7 +939,7 @@ std::vector<SearchMatch> PersistentStorage::getSearchMatchesForTokenIds(const st
|
|||||||
match.nodeType = Node::intToType(node.type);
|
match.nodeType = Node::intToType(node.type);
|
||||||
match.searchType = SearchMatch::SEARCH_TOKEN;
|
match.searchType = SearchMatch::SEARCH_TOKEN;
|
||||||
|
|
||||||
match.delimiter = nameHierarchy.getDelimiterrr();
|
match.delimiter = nameHierarchy.getDelimiter();
|
||||||
|
|
||||||
if (match.nodeType == Node::NODE_FILE)
|
if (match.nodeType == Node::NODE_FILE)
|
||||||
{
|
{
|
||||||
@@ -951,35 +958,23 @@ std::shared_ptr<Graph> PersistentStorage::getGraphForAll() const
|
|||||||
|
|
||||||
std::shared_ptr<Graph> graph = std::make_shared<Graph>();
|
std::shared_ptr<Graph> graph = std::make_shared<Graph>();
|
||||||
|
|
||||||
std::unordered_set<Id> explicitlyDefinedSymbolIds;
|
|
||||||
for (StorageSymbol symbol: m_sqliteIndexStorage.getAll<StorageSymbol>())
|
|
||||||
{
|
|
||||||
if (intToDefinitionKind(symbol.definitionKind) == DEFINITION_EXPLICIT)
|
|
||||||
{
|
|
||||||
explicitlyDefinedSymbolIds.insert(symbol.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Id> tokenIds;
|
std::vector<Id> tokenIds;
|
||||||
for (StorageNode node: m_sqliteIndexStorage.getAll<StorageNode>())
|
for (StorageNode node: m_sqliteIndexStorage.getAll<StorageNode>())
|
||||||
{
|
{
|
||||||
if (explicitlyDefinedSymbolIds.find(node.id) != explicitlyDefinedSymbolIds.end() &&
|
auto it = m_symbolDefinitionKinds.find(node.id);
|
||||||
|
if (it != m_symbolDefinitionKinds.end() && it->second == DEFINITION_EXPLICIT &&
|
||||||
(
|
(
|
||||||
!m_hierarchyCache.isChildOfVisibleNodeOrInvisible(node.id) ||
|
Node::intToType(node.type) & (Node::NODE_NAMESPACE | Node::NODE_PACKAGE) ||
|
||||||
(
|
!m_hierarchyCache.isChildOfVisibleNodeOrInvisible(node.id)
|
||||||
Node::intToType(node.type) == Node::NODE_NAMESPACE || // TODO: use & operator here
|
|
||||||
Node::intToType(node.type) == Node::NODE_PACKAGE
|
|
||||||
)
|
)
|
||||||
)
|
){
|
||||||
)
|
|
||||||
{
|
|
||||||
tokenIds.push_back(node.id);
|
tokenIds.push_back(node.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (StorageFile file: m_sqliteIndexStorage.getAll<StorageFile>())
|
for (auto p : m_fileNodePaths)
|
||||||
{
|
{
|
||||||
tokenIds.push_back(file.id);
|
tokenIds.push_back(p.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
addNodesToGraph(tokenIds, graph.get());
|
addNodesToGraph(tokenIds, graph.get());
|
||||||
@@ -1220,6 +1215,8 @@ std::shared_ptr<Graph> PersistentStorage::getGraphForTrail(
|
|||||||
// TODO: rename: getActiveElementIdsForId; TODO: make separate function for declarationId
|
// TODO: rename: getActiveElementIdsForId; TODO: make separate function for declarationId
|
||||||
std::vector<Id> PersistentStorage::getActiveTokenIdsForId(Id tokenId, Id* declarationId) const
|
std::vector<Id> PersistentStorage::getActiveTokenIdsForId(Id tokenId, Id* declarationId) const
|
||||||
{
|
{
|
||||||
|
TRACE();
|
||||||
|
|
||||||
std::vector<Id> activeTokenIds;
|
std::vector<Id> activeTokenIds;
|
||||||
|
|
||||||
if (!(m_sqliteIndexStorage.isEdge(tokenId) || m_sqliteIndexStorage.isNode(tokenId)))
|
if (!(m_sqliteIndexStorage.isEdge(tokenId) || m_sqliteIndexStorage.isNode(tokenId)))
|
||||||
@@ -1429,6 +1426,8 @@ std::shared_ptr<SourceLocationFile> PersistentStorage::getCommentLocationsInFile
|
|||||||
|
|
||||||
std::shared_ptr<TextAccess> PersistentStorage::getFileContent(const FilePath& filePath) const
|
std::shared_ptr<TextAccess> PersistentStorage::getFileContent(const FilePath& filePath) const
|
||||||
{
|
{
|
||||||
|
TRACE();
|
||||||
|
|
||||||
return m_sqliteIndexStorage.getFileContentByPath(filePath.str());
|
return m_sqliteIndexStorage.getFileContentByPath(filePath.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1620,11 +1619,14 @@ FilePath PersistentStorage::getFileNodePath(Id fileId) const
|
|||||||
|
|
||||||
bool PersistentStorage::getFileNodeComplete(const FilePath& filePath) const
|
bool PersistentStorage::getFileNodeComplete(const FilePath& filePath) const
|
||||||
{
|
{
|
||||||
std::map<FilePath, bool>::const_iterator it = m_fileNodeComplete.find(filePath);
|
auto it = m_fileNodeIds.find(filePath);
|
||||||
|
if (it != m_fileNodeIds.end())
|
||||||
if (it != m_fileNodeComplete.end())
|
|
||||||
{
|
{
|
||||||
return it->second;
|
auto it2 = m_fileNodeComplete.find(it->second);
|
||||||
|
if (it2 != m_fileNodeComplete.end())
|
||||||
|
{
|
||||||
|
return it2->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1784,26 +1786,13 @@ std::set<FilePath> PersistentStorage::getReferencingByImports(const std::set<Fil
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
Id PersistentStorage::getLastVisibleParentNodeId(const Id nodeId) const
|
|
||||||
{
|
|
||||||
return m_hierarchyCache.getLastVisibleParentNodeId(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Id> PersistentStorage::getAllChildNodeIds(const Id nodeId) const
|
|
||||||
{
|
|
||||||
std::set<Id> childNodeIds;
|
|
||||||
std::set<Id> edgeIds;
|
|
||||||
|
|
||||||
m_hierarchyCache.addAllChildIdsForNodeId(nodeId, &childNodeIds, &edgeIds);
|
|
||||||
|
|
||||||
return utility::toVector(childNodeIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PersistentStorage::addNodesToGraph(const std::vector<Id>& newNodeIds, Graph* graph) const
|
void PersistentStorage::addNodesToGraph(const std::vector<Id>& newNodeIds, Graph* graph) const
|
||||||
{
|
{
|
||||||
TRACE();
|
TRACE();
|
||||||
|
|
||||||
std::vector<Id> nodeIds;
|
std::vector<Id> nodeIds;
|
||||||
|
if (graph->getNodeCount())
|
||||||
|
{
|
||||||
for (Id id : newNodeIds)
|
for (Id id : newNodeIds)
|
||||||
{
|
{
|
||||||
if (!graph->getNodeById(id))
|
if (!graph->getNodeById(id))
|
||||||
@@ -1811,24 +1800,17 @@ void PersistentStorage::addNodesToGraph(const std::vector<Id>& newNodeIds, Graph
|
|||||||
nodeIds.push_back(id);
|
nodeIds.push_back(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nodeIds = newNodeIds;
|
||||||
|
}
|
||||||
|
|
||||||
if (nodeIds.size() == 0)
|
if (nodeIds.size() == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<Id, StorageSymbol> symbolMap;
|
|
||||||
for (const StorageSymbol& symbol : m_sqliteIndexStorage.getAllByIds<StorageSymbol>(nodeIds))
|
|
||||||
{
|
|
||||||
symbolMap[symbol.id] = symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unordered_map<Id, StorageFile> fileMap;
|
|
||||||
for (const StorageFile& file : m_sqliteIndexStorage.getAllByIds<StorageFile>(nodeIds))
|
|
||||||
{
|
|
||||||
fileMap[file.id] = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const StorageNode& storageNode : m_sqliteIndexStorage.getAllByIds<StorageNode>(nodeIds))
|
for (const StorageNode& storageNode : m_sqliteIndexStorage.getAllByIds<StorageNode>(nodeIds))
|
||||||
{
|
{
|
||||||
const Node::NodeType type = Node::intToType(storageNode.type);
|
const Node::NodeType type = Node::intToType(storageNode.type);
|
||||||
@@ -1837,10 +1819,10 @@ void PersistentStorage::addNodesToGraph(const std::vector<Id>& newNodeIds, Graph
|
|||||||
const FilePath filePath(NameHierarchy::deserialize(storageNode.serializedName).getRawName());
|
const FilePath filePath(NameHierarchy::deserialize(storageNode.serializedName).getRawName());
|
||||||
|
|
||||||
bool defined = true;
|
bool defined = true;
|
||||||
auto it = fileMap.find(storageNode.id);
|
auto it = m_fileNodeComplete.find(storageNode.id);
|
||||||
if (it != fileMap.end())
|
if (it != m_fileNodeComplete.end())
|
||||||
{
|
{
|
||||||
defined = it->second.complete;
|
defined = it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* node = graph->createNode(
|
Node* node = graph->createNode(
|
||||||
@@ -1857,10 +1839,10 @@ void PersistentStorage::addNodesToGraph(const std::vector<Id>& newNodeIds, Graph
|
|||||||
const NameHierarchy nameHierarchy = NameHierarchy::deserialize(storageNode.serializedName);
|
const NameHierarchy nameHierarchy = NameHierarchy::deserialize(storageNode.serializedName);
|
||||||
|
|
||||||
DefinitionKind defKind = DEFINITION_NONE;
|
DefinitionKind defKind = DEFINITION_NONE;
|
||||||
auto it = symbolMap.find(storageNode.id);
|
auto it = m_symbolDefinitionKinds.find(storageNode.id);
|
||||||
if (it != symbolMap.end())
|
if (it != m_symbolDefinitionKinds.end())
|
||||||
{
|
{
|
||||||
defKind = intToDefinitionKind(it->second.definitionKind);
|
defKind = it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* node = graph->createNode(
|
Node* node = graph->createNode(
|
||||||
@@ -1972,7 +1954,9 @@ void PersistentStorage::addAggregationEdgesToGraph(
|
|||||||
|
|
||||||
// build aggregation edges:
|
// build aggregation edges:
|
||||||
// get all children of the active node
|
// get all children of the active node
|
||||||
std::vector<Id> childNodeIds = getAllChildNodeIds(nodeId);
|
std::set<Id> childNodeIdsSet, edgeIdsSet;
|
||||||
|
m_hierarchyCache.addAllChildIdsForNodeId(nodeId, &childNodeIdsSet, &edgeIdsSet);
|
||||||
|
std::vector<Id> childNodeIds = utility::toVector(childNodeIdsSet);
|
||||||
if (childNodeIds.size() == 0 && edgesToAggregate.size() == 0)
|
if (childNodeIds.size() == 0 && edgesToAggregate.size() == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -2008,12 +1992,12 @@ void PersistentStorage::addAggregationEdgesToGraph(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get all parent nodes of all connected nodes (up to last level except namespace/undefined)
|
// get all parent nodes of all connected nodes (up to last level except namespace/undefined)
|
||||||
Id nodeParentNodeId = getLastVisibleParentNodeId(nodeId);
|
Id nodeParentNodeId = m_hierarchyCache.getLastVisibleParentNodeId(nodeId);
|
||||||
|
|
||||||
std::map<Id, std::vector<EdgeInfo>> connectedParentNodeIds;
|
std::map<Id, std::vector<EdgeInfo>> connectedParentNodeIds;
|
||||||
for (const std::pair<Id, std::vector<EdgeInfo>>& p : connectedNodeIds)
|
for (const std::pair<Id, std::vector<EdgeInfo>>& p : connectedNodeIds)
|
||||||
{
|
{
|
||||||
Id parentNodeId = getLastVisibleParentNodeId(p.first);
|
Id parentNodeId = m_hierarchyCache.getLastVisibleParentNodeId(p.first);
|
||||||
|
|
||||||
if (parentNodeId != nodeParentNodeId)
|
if (parentNodeId != nodeParentNodeId)
|
||||||
{
|
{
|
||||||
@@ -2084,6 +2068,8 @@ void PersistentStorage::addComponentAccessToGraph(Graph* graph) const
|
|||||||
|
|
||||||
void PersistentStorage::addCompleteFlagsToSourceLocationCollection(SourceLocationCollection* collection) const
|
void PersistentStorage::addCompleteFlagsToSourceLocationCollection(SourceLocationCollection* collection) const
|
||||||
{
|
{
|
||||||
|
TRACE();
|
||||||
|
|
||||||
collection->forEachSourceLocationFile(
|
collection->forEachSourceLocationFile(
|
||||||
[this](std::shared_ptr<SourceLocationFile> file)
|
[this](std::shared_ptr<SourceLocationFile> file)
|
||||||
{
|
{
|
||||||
@@ -2092,56 +2078,6 @@ void PersistentStorage::addCompleteFlagsToSourceLocationCollection(SourceLocatio
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PersistentStorage::buildSearchIndex()
|
|
||||||
{
|
|
||||||
TRACE();
|
|
||||||
|
|
||||||
FilePath dbPath = getDbFilePath();
|
|
||||||
|
|
||||||
std::unordered_map<Id, StorageSymbol> symbolMap;
|
|
||||||
for (StorageSymbol symbol : m_sqliteIndexStorage.getAll<StorageSymbol>())
|
|
||||||
{
|
|
||||||
symbolMap[symbol.id] = symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unordered_map<Id, StorageFile> fileMap;
|
|
||||||
for (StorageFile file : m_sqliteIndexStorage.getAll<StorageFile>())
|
|
||||||
{
|
|
||||||
fileMap[file.id] = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (StorageNode node : m_sqliteIndexStorage.getAll<StorageNode>())
|
|
||||||
{
|
|
||||||
if (Node::intToType(node.type) == Node::NODE_FILE)
|
|
||||||
{
|
|
||||||
auto it = fileMap.find(node.id);
|
|
||||||
if (it != fileMap.end())
|
|
||||||
{
|
|
||||||
FilePath filePath(it->second.filePath);
|
|
||||||
|
|
||||||
if (filePath.exists())
|
|
||||||
{
|
|
||||||
filePath = filePath.relativeTo(dbPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_fileIndex.addNode(it->second.id, filePath.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto it = symbolMap.find(node.id);
|
|
||||||
if (it == symbolMap.end() || intToDefinitionKind(it->second.definitionKind) != DEFINITION_IMPLICIT)
|
|
||||||
{
|
|
||||||
// we don't use the signature here, so elements with the same signature share the same node.
|
|
||||||
m_symbolIndex.addNode(node.id, NameHierarchy::deserialize(node.serializedName).getQualifiedName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_symbolIndex.finishSetup();
|
|
||||||
m_fileIndex.finishSetup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PersistentStorage::buildFilePathMaps()
|
void PersistentStorage::buildFilePathMaps()
|
||||||
{
|
{
|
||||||
TRACE();
|
TRACE();
|
||||||
@@ -2150,8 +2086,51 @@ void PersistentStorage::buildFilePathMaps()
|
|||||||
{
|
{
|
||||||
m_fileNodeIds.emplace(FilePath(file.filePath), file.id);
|
m_fileNodeIds.emplace(FilePath(file.filePath), file.id);
|
||||||
m_fileNodePaths.emplace(file.id, FilePath(file.filePath));
|
m_fileNodePaths.emplace(file.id, FilePath(file.filePath));
|
||||||
m_fileNodeComplete.emplace(FilePath(file.filePath), file.complete);
|
m_fileNodeComplete.emplace(file.id, file.complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (StorageSymbol symbol : m_sqliteIndexStorage.getAll<StorageSymbol>())
|
||||||
|
{
|
||||||
|
m_symbolDefinitionKinds.emplace(symbol.id, intToDefinitionKind(symbol.definitionKind));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PersistentStorage::buildSearchIndex()
|
||||||
|
{
|
||||||
|
TRACE();
|
||||||
|
|
||||||
|
FilePath dbPath = getDbFilePath();
|
||||||
|
|
||||||
|
for (StorageNode node : m_sqliteIndexStorage.getAll<StorageNode>())
|
||||||
|
{
|
||||||
|
if (Node::intToType(node.type) == Node::NODE_FILE)
|
||||||
|
{
|
||||||
|
auto it = m_fileNodePaths.find(node.id);
|
||||||
|
if (it != m_fileNodePaths.end())
|
||||||
|
{
|
||||||
|
FilePath filePath(it->second);
|
||||||
|
|
||||||
|
if (filePath.exists())
|
||||||
|
{
|
||||||
|
filePath = filePath.relativeTo(dbPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fileIndex.addNode(node.id, filePath.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto it = m_symbolDefinitionKinds.find(node.id);
|
||||||
|
if (it == m_symbolDefinitionKinds.end() || it->second != DEFINITION_IMPLICIT)
|
||||||
|
{
|
||||||
|
// we don't use the signature here, so elements with the same signature share the same node.
|
||||||
|
m_symbolIndex.addNode(node.id, NameHierarchy::deserialize(node.serializedName).getQualifiedName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_symbolIndex.finishSetup();
|
||||||
|
m_fileIndex.finishSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PersistentStorage::buildFullTextSearchIndex() const
|
void PersistentStorage::buildFullTextSearchIndex() const
|
||||||
@@ -2170,23 +2149,30 @@ void PersistentStorage::buildHierarchyCache()
|
|||||||
|
|
||||||
std::vector<StorageEdge> memberEdges = m_sqliteIndexStorage.getEdgesByType(Edge::typeToInt(Edge::EDGE_MEMBER));
|
std::vector<StorageEdge> memberEdges = m_sqliteIndexStorage.getEdgesByType(Edge::typeToInt(Edge::EDGE_MEMBER));
|
||||||
|
|
||||||
Cache<Id, Node::NodeType> nodeTypeCache([this](Id id){
|
std::vector<Id> sourceNodeIds;
|
||||||
return Node::intToType(m_sqliteIndexStorage.getFirstById<StorageNode>(id).type);
|
for (const StorageEdge& edge : memberEdges)
|
||||||
});
|
|
||||||
|
|
||||||
Cache<Id, DefinitionKind> definitionKindCache([this](Id id){
|
|
||||||
StorageSymbol symbol = m_sqliteIndexStorage.getFirstById<StorageSymbol>(id);
|
|
||||||
if (symbol.id > 0)
|
|
||||||
{
|
{
|
||||||
return intToDefinitionKind(symbol.definitionKind);
|
sourceNodeIds.push_back(edge.sourceNodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<StorageNode> sourceNodes = m_sqliteIndexStorage.getAllByIds<StorageNode>(sourceNodeIds);
|
||||||
|
|
||||||
|
std::map<Id, Node::NodeType> sourceNodeTypeMap;
|
||||||
|
for (const StorageNode& node : sourceNodes)
|
||||||
|
{
|
||||||
|
sourceNodeTypeMap.emplace(node.id, Node::intToType(node.type));
|
||||||
}
|
}
|
||||||
return DEFINITION_NONE;
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const StorageEdge& edge : memberEdges)
|
for (const StorageEdge& edge : memberEdges)
|
||||||
{
|
{
|
||||||
bool sourceIsVisible = !(nodeTypeCache.getValue(edge.sourceNodeId) & Node::NODE_NOT_VISIBLE);
|
bool sourceIsVisible = !(sourceNodeTypeMap[edge.sourceNodeId] & Node::NODE_NOT_VISIBLE);
|
||||||
bool targetIsImplicit = definitionKindCache.getValue(edge.targetNodeId) == DEFINITION_IMPLICIT;
|
|
||||||
|
bool targetIsImplicit = false;
|
||||||
|
auto it = m_symbolDefinitionKinds.find(edge.targetNodeId);
|
||||||
|
if (it != m_symbolDefinitionKinds.end())
|
||||||
|
{
|
||||||
|
targetIsImplicit = (it->second == DEFINITION_IMPLICIT);
|
||||||
|
}
|
||||||
|
|
||||||
m_hierarchyCache.createConnection(
|
m_hierarchyCache.createConnection(
|
||||||
edge.id, edge.sourceNodeId, edge.targetNodeId, sourceIsVisible, targetIsImplicit);
|
edge.id, edge.sourceNodeId, edge.targetNodeId, sourceIsVisible, targetIsImplicit);
|
||||||
|
|||||||
@@ -156,9 +156,6 @@ private:
|
|||||||
std::set<FilePath> getReferencingByIncludes(const std::set<FilePath>& filePaths);
|
std::set<FilePath> getReferencingByIncludes(const std::set<FilePath>& filePaths);
|
||||||
std::set<FilePath> getReferencingByImports(const std::set<FilePath>& filePaths);
|
std::set<FilePath> getReferencingByImports(const std::set<FilePath>& filePaths);
|
||||||
|
|
||||||
Id getLastVisibleParentNodeId(const Id nodeId) const;
|
|
||||||
std::vector<Id> getAllChildNodeIds(const Id nodeId) const;
|
|
||||||
|
|
||||||
void addNodesToGraph(const std::vector<Id>& nodeIds, Graph* graph) const;
|
void addNodesToGraph(const std::vector<Id>& nodeIds, Graph* graph) const;
|
||||||
void addEdgesToGraph(const std::vector<Id>& edgeIds, Graph* graph) const;
|
void addEdgesToGraph(const std::vector<Id>& edgeIds, Graph* graph) const;
|
||||||
void addNodesWithParentsAndEdgesToGraph(
|
void addNodesWithParentsAndEdgesToGraph(
|
||||||
@@ -169,8 +166,8 @@ private:
|
|||||||
|
|
||||||
void addCompleteFlagsToSourceLocationCollection(SourceLocationCollection* collection) const;
|
void addCompleteFlagsToSourceLocationCollection(SourceLocationCollection* collection) const;
|
||||||
|
|
||||||
void buildSearchIndex();
|
|
||||||
void buildFilePathMaps();
|
void buildFilePathMaps();
|
||||||
|
void buildSearchIndex();
|
||||||
void buildFullTextSearchIndex() const;
|
void buildFullTextSearchIndex() const;
|
||||||
void buildHierarchyCache();
|
void buildHierarchyCache();
|
||||||
|
|
||||||
@@ -187,7 +184,9 @@ private:
|
|||||||
|
|
||||||
std::map<FilePath, Id> m_fileNodeIds;
|
std::map<FilePath, Id> m_fileNodeIds;
|
||||||
std::map<Id, FilePath> m_fileNodePaths;
|
std::map<Id, FilePath> m_fileNodePaths;
|
||||||
std::map <FilePath, bool> m_fileNodeComplete;
|
std::map<Id, bool> m_fileNodeComplete;
|
||||||
|
|
||||||
|
std::map<Id, DefinitionKind> m_symbolDefinitionKinds;
|
||||||
|
|
||||||
HierarchyCache m_hierarchyCache;
|
HierarchyCache m_hierarchyCache;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ std::string NameElement::Signature::serialize(Signature signature)
|
|||||||
|
|
||||||
NameElement::Signature NameElement::Signature::deserialize(const std::string& serialized)
|
NameElement::Signature NameElement::Signature::deserialize(const std::string& serialized)
|
||||||
{
|
{
|
||||||
|
if (serialized == "\tp")
|
||||||
|
{
|
||||||
|
return Signature();
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> serializedElements = utility::splitToVector(serialized, "\tp");
|
std::vector<std::string> serializedElements = utility::splitToVector(serialized, "\tp");
|
||||||
if (serializedElements.size() != 2)
|
if (serializedElements.size() != 2)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
std::string NameHierarchy::serialize(NameHierarchy nameHierarchy)
|
std::string NameHierarchy::serialize(NameHierarchy nameHierarchy)
|
||||||
{
|
{
|
||||||
std::string serializedName = nameDelimiterTypeToString(nameHierarchy.getDelimiterrr()) + "\tm";
|
std::string serializedName = nameDelimiterTypeToString(nameHierarchy.getDelimiter()) + "\tm";
|
||||||
for (size_t i = 0; i < nameHierarchy.size(); i++)
|
for (size_t i = 0; i < nameHierarchy.size(); i++)
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
@@ -45,12 +45,12 @@ NameHierarchy NameHierarchy::deserialize(const std::string& serializedName)
|
|||||||
return nameHierarchy;
|
return nameHierarchy;
|
||||||
}
|
}
|
||||||
|
|
||||||
NameDelimiterType NameHierarchy::getDelimiterrr() const
|
NameDelimiterType NameHierarchy::getDelimiter() const
|
||||||
{
|
{
|
||||||
return m_delimiter;
|
return m_delimiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NameHierarchy::setDelimiterrr(const NameDelimiterType delimiter)
|
void NameHierarchy::setDelimiter(const NameDelimiterType delimiter)
|
||||||
{
|
{
|
||||||
m_delimiter = delimiter;
|
m_delimiter = delimiter;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ public:
|
|||||||
NameHierarchy(const std::vector<std::string>& names, const NameDelimiterType delimiter);
|
NameHierarchy(const std::vector<std::string>& names, const NameDelimiterType delimiter);
|
||||||
~NameHierarchy();
|
~NameHierarchy();
|
||||||
|
|
||||||
NameDelimiterType getDelimiterrr() const;
|
NameDelimiterType getDelimiter() const;
|
||||||
void setDelimiterrr(const NameDelimiterType delimiter);
|
void setDelimiter(const NameDelimiterType delimiter);
|
||||||
|
|
||||||
void push(std::shared_ptr<NameElement> element);
|
void push(std::shared_ptr<NameElement> element);
|
||||||
void pop();
|
void pop();
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ Id ParserClientImpl::addNodeHierarchy(NameHierarchy nameHierarchy, Node::NodeTyp
|
|||||||
}
|
}
|
||||||
|
|
||||||
Id parentNodeId = 0;
|
Id parentNodeId = 0;
|
||||||
NameHierarchy currentNameHierarchy(nameHierarchy.getDelimiterrr());
|
NameHierarchy currentNameHierarchy(nameHierarchy.getDelimiter());
|
||||||
|
|
||||||
for (size_t i = 0; i < nameHierarchy.size(); i++)
|
for (size_t i = 0; i < nameHierarchy.size(); i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,15 +23,14 @@ void SearchIndex::addNode(Id id, const std::string& name)
|
|||||||
std::string remaining = name;
|
std::string remaining = name;
|
||||||
while (remaining.size() > 0)
|
while (remaining.size() > 0)
|
||||||
{
|
{
|
||||||
bool matchingEdgeFound = false;
|
auto it = currentNode->edges.find(remaining[0]);
|
||||||
// has edge starting with c?
|
if (it != currentNode->edges.end())
|
||||||
for (size_t i = 0; i < currentNode->edges.size(); i++)
|
|
||||||
{
|
{
|
||||||
Edge* currentEdge = currentNode->edges[i];
|
Edge* currentEdge = it->second;
|
||||||
const std::string& edgeString = currentEdge->s;
|
const std::string& edgeString = currentEdge->s;
|
||||||
|
|
||||||
size_t matchCount = 0;
|
size_t matchCount = 1;
|
||||||
for (size_t j = 0; j < edgeString.size() && j < remaining.size(); j++)
|
for (size_t j = 1; j < edgeString.size() && j < remaining.size(); j++)
|
||||||
{
|
{
|
||||||
if (edgeString[j] != remaining[j])
|
if (edgeString[j] != remaining[j])
|
||||||
{
|
{
|
||||||
@@ -40,9 +39,6 @@ void SearchIndex::addNode(Id id, const std::string& name)
|
|||||||
matchCount++;
|
matchCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchCount != 0)
|
|
||||||
{
|
|
||||||
remaining = remaining.substr(matchCount);
|
|
||||||
if (matchCount < edgeString.size())
|
if (matchCount < edgeString.size())
|
||||||
{
|
{
|
||||||
// split current edge
|
// split current edge
|
||||||
@@ -51,21 +47,19 @@ void SearchIndex::addNode(Id id, const std::string& name)
|
|||||||
std::shared_ptr<Edge> e = std::make_shared<Edge>();
|
std::shared_ptr<Edge> e = std::make_shared<Edge>();
|
||||||
m_edges.push_back(e);
|
m_edges.push_back(e);
|
||||||
|
|
||||||
n->edges.push_back(e.get());
|
|
||||||
|
|
||||||
e->s = edgeString.substr(matchCount);
|
e->s = edgeString.substr(matchCount);
|
||||||
e->target = currentEdge->target;
|
e->target = currentEdge->target;
|
||||||
|
|
||||||
|
n->edges.emplace(e->s[0], e.get());
|
||||||
|
|
||||||
currentEdge->s = edgeString.substr(0, matchCount);
|
currentEdge->s = edgeString.substr(0, matchCount);
|
||||||
currentEdge->target = n.get();
|
currentEdge->target = n.get();
|
||||||
}
|
}
|
||||||
currentNode = currentEdge->target;
|
|
||||||
matchingEdgeFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!matchingEdgeFound)
|
remaining = remaining.substr(matchCount);
|
||||||
|
currentNode = currentEdge->target;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
std::shared_ptr<Node> n = std::make_shared<Node>();
|
std::shared_ptr<Node> n = std::make_shared<Node>();
|
||||||
m_nodes.push_back(n);
|
m_nodes.push_back(n);
|
||||||
@@ -75,7 +69,7 @@ void SearchIndex::addNode(Id id, const std::string& name)
|
|||||||
e->s = remaining;
|
e->s = remaining;
|
||||||
e->target = n.get();
|
e->target = n.get();
|
||||||
|
|
||||||
currentNode->edges.push_back(e.get());
|
currentNode->edges.emplace(e->s[0], e.get());
|
||||||
currentNode = n.get();
|
currentNode = n.get();
|
||||||
|
|
||||||
remaining = "";
|
remaining = "";
|
||||||
@@ -87,9 +81,9 @@ void SearchIndex::addNode(Id id, const std::string& name)
|
|||||||
|
|
||||||
void SearchIndex::finishSetup()
|
void SearchIndex::finishSetup()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_root->edges.size(); i++)
|
for (auto p : m_root->edges)
|
||||||
{
|
{
|
||||||
populateEdgeGate(m_root->edges[i]);
|
populateEdgeGate(p.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,9 +133,9 @@ std::vector<SearchResult> SearchIndex::search(
|
|||||||
void SearchIndex::populateEdgeGate(Edge* e)
|
void SearchIndex::populateEdgeGate(Edge* e)
|
||||||
{
|
{
|
||||||
Node* target = e->target;
|
Node* target = e->target;
|
||||||
for (size_t i = 0; i < target->edges.size(); i++)
|
for (auto p : target->edges)
|
||||||
{
|
{
|
||||||
Edge* targetEdge = target->edges[i];
|
Edge* targetEdge = p.second;
|
||||||
populateEdgeGate(targetEdge);
|
populateEdgeGate(targetEdge);
|
||||||
utility::append(e->gate, targetEdge->gate);
|
utility::append(e->gate, targetEdge->gate);
|
||||||
}
|
}
|
||||||
@@ -160,8 +154,10 @@ void SearchIndex::searchRecursive(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const Edge* currentEdge : path.node->edges)
|
for (auto p : path.node->edges)
|
||||||
{
|
{
|
||||||
|
const Edge* currentEdge = p.second;
|
||||||
|
|
||||||
// test if s passes the edge's gate.
|
// test if s passes the edge's gate.
|
||||||
bool passesGate = true;
|
bool passesGate = true;
|
||||||
for (const char& c : remainingQuery)
|
for (const char& c : remainingQuery)
|
||||||
@@ -242,8 +238,9 @@ std::multiset<SearchResult> SearchIndex::createScoredResults(const std::vector<P
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const Edge* edge : path.node->edges)
|
for (auto p : path.node->edges)
|
||||||
{
|
{
|
||||||
|
const Edge* edge = p.second;
|
||||||
Path nextPath;
|
Path nextPath;
|
||||||
nextPath.indices = path.indices;
|
nextPath.indices = path.indices;
|
||||||
nextPath.node = edge->target;
|
nextPath.node = edge->target;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ private:
|
|||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
std::set<Id> elementIds;
|
std::set<Id> elementIds;
|
||||||
std::vector<Edge*> edges;
|
std::map<char, Edge*> edges;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Edge
|
struct Edge
|
||||||
|
|||||||
Reference in New Issue
Block a user