logic: Only request unconnected child nodes when expanding node

* increases graph performance by ~30%
This commit is contained in:
Eberhard Graether
2017-06-01 14:48:03 +02:00
parent 8660ab5b14
commit aaca8618e2
13 changed files with 336 additions and 219 deletions
@@ -268,44 +268,73 @@ void GraphController::handleMessage(MessageGraphNodeExpand* message)
return;
}
DummyNode* node = getDummyGraphNodeById(message->tokenId);
if (node)
Id nodeId = message->tokenId;
DummyNode* dummyNode = getDummyGraphNodeById(nodeId);
if (dummyNode)
{
if (!node->active && message->expand)
dummyNode->expanded = message->expand;
if (message->expand && dummyNode->hasMissingChildNodes())
{
for (size_t i = 0, l = m_dummyEdges.size(); i < l; i++)
{
std::shared_ptr<DummyEdge> edge = m_dummyEdges[i];
std::shared_ptr<Graph> childGraph = m_storageAccess->getGraphForChildrenOfNodeId(nodeId);
if (edge && edge->data && edge->data->isType(Edge::EDGE_AGGREGATION) &&
(edge->targetId == node->tokenId || edge->ownerId == node->tokenId))
childGraph->getNodeById(nodeId)->forEachEdgeOfType(Edge::EDGE_MEMBER,
[this](Edge* edge)
{
std::vector<Id> aggregationIds =
utility::toVector<Id>(edge->data->getComponent<TokenComponentAggregation>()->getAggregationIds());
m_graph->addEdgeAsPlainCopy(edge);
}
);
if (m_graph->getEdgeById(aggregationIds[0]) != nullptr)
Node* node = m_graph->getNodeById(nodeId);
std::vector<std::shared_ptr<DummyNode>> newDummyNodes = createDummyNodeTopDown(node, node->getLastParentNode()->getId());
if (newDummyNodes.size() != 1)
{
LOG_ERROR("Wrong amount of dummy nodes created");
return;
}
std::shared_ptr<DummyNode> newDummyNode = newDummyNodes[0];
// replace newer dummy graph nodes with the old ones. Nodes will have the correct sorting after that.
newDummyNode->replaceSubGraphNodes(dummyNode->getSubGraphNodes());
// move all newer and older dummy graph nodes into the old dummy node
dummyNode->replaceAccessNodes(newDummyNode->getAccessNodes());
if (!dummyNode->active && message->expand)
{
for (size_t i = 0, l = m_dummyEdges.size(); i < l; i++)
{
std::shared_ptr<DummyEdge> edge = m_dummyEdges[i];
if (edge && edge->data && edge->data->isType(Edge::EDGE_AGGREGATION) &&
(edge->targetId == dummyNode->tokenId || edge->ownerId == dummyNode->tokenId))
{
break;
}
std::vector<Id> aggregationIds =
utility::toVector<Id>(edge->data->getComponent<TokenComponentAggregation>()->getAggregationIds());
std::shared_ptr<Graph> graph = m_storageAccess->getGraphForActiveTokenIds(aggregationIds);
graph->forEachEdge(
[this](Edge* e)
if (m_graph->getEdgeById(aggregationIds[0]) != nullptr)
{
if (!e->isType(Edge::EDGE_MEMBER))
{
m_dummyEdges.push_back(std::make_shared<DummyEdge>(
e->getFrom()->getId(), e->getTo()->getId(), m_graph->addEdgeAsPlainCopy(e)));
}
break;
}
);
std::shared_ptr<Graph> aggregationGraph = m_storageAccess->getGraphForActiveTokenIds(aggregationIds);
aggregationGraph->forEachEdge(
[this](Edge* e)
{
if (!e->isType(Edge::EDGE_MEMBER))
{
m_dummyEdges.push_back(std::make_shared<DummyEdge>(
e->getFrom()->getId(), e->getTo()->getId(), m_graph->addEdgeAsPlainCopy(e)));
}
}
);
}
}
}
}
node->expanded = message->expand;
setActiveAndVisibility(utility::concat(m_activeNodeIds, m_activeEdgeIds));
layoutNesting();
@@ -616,8 +645,6 @@ void GraphController::setVisibility(bool noActive)
for (std::shared_ptr<DummyNode> node : m_dummyNodes)
{
removeImplicitChildrenRecursive(node.get());
setNodeVisibilityRecursiveBottomUp(node.get(), noActive);
}
}
@@ -649,41 +676,6 @@ void GraphController::setNodeActiveRecursive(DummyNode* node, const std::vector<
}
}
void GraphController::removeImplicitChildrenRecursive(DummyNode* node)
{
if (node->isGraphNode() && !node->data->isExplicit())
{
return;
}
for (size_t i = 0; i < node->subNodes.size(); i++)
{
bool removeNode = false;
DummyNode* subNode = node->subNodes[i].get();
if (subNode->isGraphNode() && subNode->data->isImplicit() &&
!subNode->connected && !subNode->active && !subNode->subNodes.size())
{
removeNode = true;
}
else
{
removeImplicitChildrenRecursive(subNode);
if (subNode->isAccessNode() && subNode->subNodes.size() == 0)
{
removeNode = true;
}
}
if (removeNode)
{
node->subNodes.erase(node->subNodes.begin() + i);
i--;
}
}
}
bool GraphController::setNodeVisibilityRecursiveBottomUp(DummyNode* node, bool noActive) const
{
node->visible = false;
@@ -1310,8 +1302,10 @@ void GraphController::layoutNestingRecursive(DummyNode* node) const
width = margins.charWidth * node->name.size();
if (node->data->isType(Node::NODE_TYPE | Node::NODE_BUILTIN_TYPE | Node::NODE_CLASS | Node::NODE_STRUCT | Node::NODE_ENUM) &&
node->subNodes.size())
Node::NodeTypeMask mask =
Node::NODE_NON_INDEXED | Node::NODE_TYPE | Node::NODE_BUILTIN_TYPE |
Node::NODE_CLASS | Node::NODE_STRUCT | Node::NODE_ENUM;
if (node->data->isType(mask) && node->data->getChildCount() > 0)
{
addExpandToggleNode(node);
}
@@ -1417,7 +1411,7 @@ void GraphController::addExpandToggleNode(DummyNode* node) const
expandNode->visible = true;
expandNode->expanded = node->expanded;
bool hasVisibleSubNode = false;
size_t visibleSubNodeCount = 0;
for (size_t i = 0; i < node->subNodes.size(); i++)
{
DummyNode* subNode = node->subNodes[i].get();
@@ -1436,18 +1430,15 @@ void GraphController::addExpandToggleNode(DummyNode* node) const
for (std::shared_ptr<DummyNode> subSubNode : subNode->subNodes)
{
if (!subSubNode->visible)
if (subSubNode->visible && (!subSubNode->isGraphNode() || !subSubNode->data->isImplicit()))
{
expandNode->invisibleSubNodeCount++;
}
else
{
hasVisibleSubNode = true;
visibleSubNodeCount++;
}
}
}
if ((expandNode->isExpanded() && hasVisibleSubNode) || expandNode->invisibleSubNodeCount)
expandNode->invisibleSubNodeCount = node->data->getChildCount() - visibleSubNodeCount;
if ((expandNode->isExpanded() && visibleSubNodeCount > 0) || expandNode->invisibleSubNodeCount)
{
node->subNodes.push_back(expandNode);
}
@@ -85,7 +85,6 @@ private:
void setVisibility(bool noActive);
void setActiveAndVisibility(const std::vector<Id>& activeTokenIds);
void setNodeActiveRecursive(DummyNode* node, const std::vector<Id>& activeTokenIds, bool* noActive) const;
void removeImplicitChildrenRecursive(DummyNode* node);
bool setNodeVisibilityRecursiveBottomUp(DummyNode* node, bool noActive) const;
void setNodeVisibilityRecursiveTopDown(DummyNode* node, bool parentExpanded) const;
@@ -238,6 +238,104 @@ public:
return bundleId;
}
bool hasMissingChildNodes() const
{
size_t childCount = 0;
if (isGraphNode())
{
childCount = data->getChildCount();
}
size_t subNodeCount = 0;
for (std::shared_ptr<DummyNode> subNode : subNodes)
{
if (subNode->isAccessNode())
{
for (std::shared_ptr<DummyNode> subSubNode : subNode->subNodes)
{
if (subSubNode->isGraphNode() && !subSubNode->data->isImplicit())
{
subNodeCount++;
}
}
}
}
return subNodeCount < childCount;
}
std::map<Id, std::shared_ptr<DummyNode>> getSubGraphNodes() const
{
std::map<Id, std::shared_ptr<DummyNode>> subGraphNodes;
for (std::shared_ptr<DummyNode> subNode : subNodes)
{
if (subNode->isAccessNode())
{
for (std::shared_ptr<DummyNode> subSubNode : subNode->subNodes)
{
if (subSubNode->isGraphNode())
{
subGraphNodes.emplace(subSubNode->tokenId, subSubNode);
}
}
}
}
return subGraphNodes;
}
void replaceSubGraphNodes(std::map<Id, std::shared_ptr<DummyNode>> subGraphNodes) const
{
for (std::shared_ptr<DummyNode> subNode : subNodes)
{
if (subNode->isAccessNode())
{
for (size_t i = 0; i < subNode->subNodes.size(); i++)
{
std::shared_ptr<DummyNode> subSubNode = subNode->subNodes[i];
if (!subSubNode->isGraphNode())
{
continue;
}
auto it = subGraphNodes.find(subSubNode->tokenId);
if (it != subGraphNodes.end())
{
subNode->subNodes[i] = it->second;
subGraphNodes.erase(it);
}
}
}
}
}
std::vector<std::shared_ptr<DummyNode>> getAccessNodes() const
{
std::vector<std::shared_ptr<DummyNode>> accessNodes;
for (std::shared_ptr<DummyNode> subNode : subNodes)
{
if (subNode->isAccessNode())
{
accessNodes.push_back(subNode);
}
}
return accessNodes;
}
void replaceAccessNodes(const std::vector<std::shared_ptr<DummyNode>>& accessNodes)
{
for (size_t i = 0; i < subNodes.size(); i++)
{
if (subNodes[i]->isAccessNode())
{
subNodes.erase(subNodes.begin() + i);
i--;
}
}
subNodes.insert(subNodes.end(), accessNodes.begin(), accessNodes.end());
}
Vec2i position;
Vec2i size;
+37 -64
View File
@@ -5,7 +5,7 @@ HierarchyCache::HierarchyNode::HierarchyNode(Id nodeId)
, m_edgeId(0)
, m_parent(nullptr)
, m_isVisible(true)
, m_isIndexed(true)
, m_isImplicit(false)
{
}
@@ -39,25 +39,33 @@ void HierarchyCache::HierarchyNode::addChild(HierarchyNode* child)
m_children.push_back(child);
}
const std::vector<HierarchyCache::HierarchyNode*>& HierarchyCache::HierarchyNode::getChildren() const
size_t HierarchyCache::HierarchyNode::getChildrenCount() const
{
return m_children;
return m_children.size();
}
void HierarchyCache::HierarchyNode::addChildIds(std::vector<Id>* nodeIds) const
size_t HierarchyCache::HierarchyNode::getNonImplicitChildrenCount() const
{
size_t count = 0;
for (const HierarchyNode* child : m_children)
{
nodeIds->push_back(child->getNodeId());
if (!child->isImplicit())
{
count++;
}
}
return count;
}
void HierarchyCache::HierarchyNode::addChildIds(std::set<Id>* nodeIds, std::set<Id>* edgeIds) const
void HierarchyCache::HierarchyNode::addNonImplicitChildIds(std::vector<Id>* nodeIds, std::vector<Id>* edgeIds) const
{
for (const HierarchyNode* child : m_children)
{
nodeIds->insert(child->getNodeId());
edgeIds->insert(child->getEdgeId());
if (!child->isImplicit())
{
nodeIds->push_back(child->getNodeId());
edgeIds->push_back(child->getEdgeId());
}
}
}
@@ -72,21 +80,6 @@ void HierarchyCache::HierarchyNode::addChildIdsRecursive(std::set<Id>* nodeIds,
}
}
void HierarchyCache::HierarchyNode::addVisibleNodeIdsRecursive(std::vector<Id>* nodeIds) const
{
if (isVisible())
{
nodeIds->push_back(getNodeId());
}
else
{
for (const HierarchyNode* child : m_children)
{
child->addVisibleNodeIdsRecursive(nodeIds);
}
}
}
bool HierarchyCache::HierarchyNode::isVisible() const
{
return m_isVisible;
@@ -97,14 +90,14 @@ void HierarchyCache::HierarchyNode::setIsVisible(bool isVisible)
m_isVisible = isVisible;
}
bool HierarchyCache::HierarchyNode::isIndexed() const
bool HierarchyCache::HierarchyNode::isImplicit() const
{
return m_isIndexed;
return m_isImplicit;
}
void HierarchyCache::HierarchyNode::setIsIndexed(bool isIndexed)
void HierarchyCache::HierarchyNode::setIsImplicit(bool isImplicit)
{
m_isIndexed = isIndexed;
m_isImplicit = isImplicit;
}
@@ -113,7 +106,7 @@ void HierarchyCache::clear()
m_nodes.clear();
}
void HierarchyCache::createConnection(Id edgeId, Id fromId, Id toId, bool sourceVisible, bool sourceIndexed, bool targetIndexed)
void HierarchyCache::createConnection(Id edgeId, Id fromId, Id toId, bool sourceVisible, bool targetImplicit)
{
HierarchyNode* from = createNode(fromId);
HierarchyNode* to = createNode(toId);
@@ -122,10 +115,9 @@ void HierarchyCache::createConnection(Id edgeId, Id fromId, Id toId, bool source
to->setParent(from);
from->setIsVisible(sourceVisible);
from->setIsIndexed(sourceIndexed);
to->setEdgeId(edgeId);
to->setIsIndexed(targetIndexed);
to->setIsImplicit(targetImplicit);
}
Id HierarchyCache::getLastVisibleParentNodeId(Id nodeId) const
@@ -170,23 +162,9 @@ size_t HierarchyCache::getIndexOfLastVisibleParentNode(Id nodeId) const
return idx;
}
void HierarchyCache::addAllChildIdsForNodeId(Id nodeId, std::set<Id>* nodeIds, std::set<Id>* edgeIds) const
void HierarchyCache::addAllVisibleParentIdsForNodeId(Id nodeId, std::set<Id>* nodeIds, std::set<Id>* edgeIds) const
{
HierarchyNode* node = getNode(nodeId);
if (node && node->isVisible())
{
node->addChildIdsRecursive(nodeIds, edgeIds);
}
}
void HierarchyCache::addAllVisibleParentsAndChildIdsForNodeId(Id nodeId, std::set<Id>* nodeIds, std::set<Id>* edgeIds) const
{
HierarchyNode* node = getNode(nodeId);
if (node && node->isVisible())
{
node->addChildIds(nodeIds, edgeIds);
}
Id edgeId = 0;
while (node && node->isVisible())
{
@@ -202,26 +180,32 @@ void HierarchyCache::addAllVisibleParentsAndChildIdsForNodeId(Id nodeId, std::se
}
}
void HierarchyCache::addFirstChildIdsForNodeId(Id nodeId, std::vector<Id>* nodeIds) const
void HierarchyCache::addAllChildIdsForNodeId(Id nodeId, std::set<Id>* nodeIds, std::set<Id>* edgeIds) const
{
HierarchyNode* node = getNode(nodeId);
if (node)
if (node && node->isVisible())
{
node->addChildIds(nodeIds);
node->addChildIdsRecursive(nodeIds, edgeIds);
}
}
void HierarchyCache::addFirstVisibleChildIdsForNodeId(Id nodeId, std::vector<Id>* nodeIds) const
void HierarchyCache::addFirstNonImplicitChildIdsForNodeId(Id nodeId, std::vector<Id>* nodeIds, std::vector<Id>* edgeIds) const
{
HierarchyNode* node = getNode(nodeId);
if (node)
{
node->addVisibleNodeIdsRecursive(nodeIds);
node->addNonImplicitChildIds(nodeIds, edgeIds);
}
else
}
size_t HierarchyCache::getFirstNonImplicitChildIdsCountForNodeId(Id nodeId) const
{
HierarchyNode* node = getNode(nodeId);
if (node)
{
nodeIds->push_back(nodeId);
return node->getNonImplicitChildrenCount();
}
return 0;
}
bool HierarchyCache::isChildOfVisibleNodeOrInvisible(Id nodeId) const
@@ -245,23 +229,12 @@ bool HierarchyCache::isChildOfVisibleNodeOrInvisible(Id nodeId) const
return false;
}
bool HierarchyCache::isIndexed(Id nodeId) const
{
HierarchyNode* node = getNode(nodeId);
if (!node)
{
return true;
}
return node->isIndexed();
}
bool HierarchyCache::nodeHasChildren(Id nodeId) const
{
HierarchyNode* node = getNode(nodeId);
if (node)
{
return node->getChildren().size();
return node->getChildrenCount();
}
return false;
+13 -14
View File
@@ -13,20 +13,19 @@ class HierarchyCache
public:
void clear();
void createConnection(Id edgeId, Id fromId, Id toId, bool sourceVisible, bool sourceIndexed, bool targetIndexed);
void createConnection(Id edgeId, Id fromId, Id toId, bool sourceVisible, bool targetImplicit);
Id getLastVisibleParentNodeId(Id nodeId) const;
size_t getIndexOfLastVisibleParentNode(Id nodeId) const;
void addAllChildIdsForNodeId(Id nodeId, std::set<Id>* nodeIds, std::set<Id>* edgeIds) const;
void addAllVisibleParentsAndChildIdsForNodeId(Id nodeId, std::set<Id>* nodeIds, std::set<Id>* edgeIds) const;
void addAllVisibleParentsRecursive(Id nodeId, std::set<Id>* nodeIds, std::set<Id>* edgeIds) const;
void addAllVisibleParentIdsForNodeId(Id nodeId, std::set<Id>* nodeIds, std::set<Id>* edgeIds) const;
void addFirstChildIdsForNodeId(Id nodeId, std::vector<Id>* nodeIds) const;
void addFirstVisibleChildIdsForNodeId(Id nodeId, std::vector<Id>* nodeIds) const;
void addAllChildIdsForNodeId(Id nodeId, std::set<Id>* nodeIds, std::set<Id>* edgeIds) const;
void addFirstNonImplicitChildIdsForNodeId(Id nodeId, std::vector<Id>* nodeIds, std::vector<Id>* edgeIds) const;
size_t getFirstNonImplicitChildIdsCountForNodeId(Id nodeId) const;
bool isChildOfVisibleNodeOrInvisible(Id nodeId) const;
bool isIndexed(Id nodeId) const;
bool nodeHasChildren(Id nodeId) const;
@@ -45,18 +44,18 @@ private:
void setParent(HierarchyNode* parent);
void addChild(HierarchyNode* child);
const std::vector<HierarchyNode*>& getChildren() const;
void addChildIds(std::vector<Id>* nodeIds) const;
void addChildIds(std::set<Id>* nodeIds, std::set<Id>* edgeIds) const;
size_t getChildrenCount() const;
size_t getNonImplicitChildrenCount() const;
void addNonImplicitChildIds(std::vector<Id>* nodeIds, std::vector<Id>* edgeIds) const;
void addChildIdsRecursive(std::set<Id>* nodeIds, std::set<Id>* edgeIds) const;
void addVisibleNodeIdsRecursive(std::vector<Id>* nodeIds) const;
bool isVisible() const;
void setIsVisible(bool isVisible);
bool isIndexed() const;
void setIsIndexed(bool isIndexed);
bool isImplicit() const;
void setIsImplicit(bool isImplicit);
private:
const Id m_nodeId;
@@ -66,7 +65,7 @@ private:
std::vector<HierarchyNode*> m_children;
bool m_isVisible;
bool m_isIndexed;
bool m_isImplicit;
};
HierarchyNode* getNode(Id nodeId) const;
+45 -43
View File
@@ -991,9 +991,6 @@ std::shared_ptr<Graph> PersistentStorage::getGraphForActiveTokenIds(
{
TRACE();
std::shared_ptr<Graph> g = std::make_shared<Graph>();
Graph* graph = g.get();
std::vector<Id> ids(tokenIds);
bool isNamespace = false;
@@ -1014,13 +1011,16 @@ std::shared_ptr<Graph> PersistentStorage::getGraphForActiveTokenIds(
if (nodeType & (Node::NODE_NAMESPACE | Node::NODE_PACKAGE))
{
ids.clear();
m_hierarchyCache.addFirstChildIdsForNodeId(elementId, &ids);
m_hierarchyCache.addFirstNonImplicitChildIdsForNodeId(elementId, &ids, &edgeIds);
edgeIds.clear();
isNamespace = true;
}
else
{
nodeIds.push_back(elementId);
m_hierarchyCache.addFirstNonImplicitChildIdsForNodeId(elementId, &nodeIds, &edgeIds);
edgeIds.clear();
std::vector<StorageEdge> edges = m_sqliteIndexStorage.getEdgesBySourceOrTargetId(elementId);
for (const StorageEdge& edge : edges)
@@ -1086,13 +1086,16 @@ std::shared_ptr<Graph> PersistentStorage::getGraphForActiveTokenIds(
}
}
std::shared_ptr<Graph> g = std::make_shared<Graph>();
Graph* graph = g.get();
if (isNamespace)
{
addNodesToGraph(nodeIds, graph);
}
else
{
addNodesWithChildrenAndEdgesToGraph(nodeIds, edgeIds, graph);
addNodesWithParentsAndEdgesToGraph(nodeIds, edgeIds, graph);
}
if (addAggregations)
@@ -1110,6 +1113,24 @@ std::shared_ptr<Graph> PersistentStorage::getGraphForActiveTokenIds(
return g;
}
std::shared_ptr<Graph> PersistentStorage::getGraphForChildrenOfNodeId(Id nodeId) const
{
TRACE();
std::vector<Id> nodeIds;
std::vector<Id> edgeIds;
nodeIds.push_back(nodeId);
m_hierarchyCache.addFirstNonImplicitChildIdsForNodeId(nodeId, &nodeIds, &edgeIds);
std::shared_ptr<Graph> graph = std::make_shared<Graph>();
addNodesToGraph(nodeIds, graph.get());
addEdgesToGraph(edgeIds, graph.get());
addComponentAccessToGraph(graph.get());
return graph;
}
std::shared_ptr<Graph> PersistentStorage::getGraphForTrail(
Id originId, Id targetId, Edge::EdgeTypeMask trailType, size_t depth) const
{
@@ -1169,7 +1190,7 @@ std::shared_ptr<Graph> PersistentStorage::getGraphForTrail(
std::shared_ptr<Graph> graph = std::make_shared<Graph>();
addNodesWithChildrenAndEdgesToGraph(utility::toVector(nodeIds), utility::toVector(edgeIds), graph.get());
addNodesWithParentsAndEdgesToGraph(utility::toVector(nodeIds), utility::toVector(edgeIds), graph.get());
addComponentAccessToGraph(graph.get());
return graph;
@@ -1838,6 +1859,8 @@ void PersistentStorage::addNodesToGraph(const std::vector<Id>& nodeIds, Graph* g
);
}
}
node->setChildCount(m_hierarchyCache.getFirstNonImplicitChildIdsCountForNodeId(storageNode.id));
}
}
}
@@ -1867,50 +1890,31 @@ void PersistentStorage::addEdgesToGraph(const std::vector<Id>& edgeIds, Graph* g
}
}
void PersistentStorage::addNodesWithChildrenAndEdgesToGraph(
void PersistentStorage::addNodesWithParentsAndEdgesToGraph(
const std::vector<Id>& nodeIds, const std::vector<Id>& edgeIds, Graph* graph
) const
{
TRACE();
std::vector<Id> nodeIdsFull = nodeIds;
std::set<Id> allNodeIds(nodeIds.begin(), nodeIds.end());
std::set<Id> allEdgeIds(edgeIds.begin(), edgeIds.end());
if (edgeIds.size() > 0)
{
for (const StorageEdge& storageEdge : m_sqliteIndexStorage.getAllByIds<StorageEdge>(edgeIds))
{
nodeIdsFull.push_back(storageEdge.sourceNodeId);
nodeIdsFull.push_back(storageEdge.targetNodeId);
allNodeIds.insert(storageEdge.sourceNodeId);
allNodeIds.insert(storageEdge.targetNodeId);
}
}
std::set<Id> parentNodeIds;
std::set<Id> nonIndexedNodeIds;
for (Id nodeId : nodeIdsFull)
for (Id nodeId : allNodeIds)
{
if (m_hierarchyCache.isIndexed(nodeId))
{
parentNodeIds.insert(getLastVisibleParentNodeId(nodeId));
}
else
{
nonIndexedNodeIds.insert(nodeId);
}
m_hierarchyCache.addAllVisibleParentIdsForNodeId(nodeId, &parentNodeIds, &allEdgeIds);
}
std::set<Id> allNodeIds;
std::set<Id> allEdgeIds(edgeIds.begin(), edgeIds.end());
for (Id parentNodeId : parentNodeIds)
{
allNodeIds.insert(parentNodeId);
m_hierarchyCache.addAllChildIdsForNodeId(parentNodeId, &allNodeIds, &allEdgeIds);
}
for (Id nonIndexedNodeId : nonIndexedNodeIds)
{
m_hierarchyCache.addAllVisibleParentsAndChildIdsForNodeId(nonIndexedNodeId, &allNodeIds, &allEdgeIds);
}
allNodeIds.insert(parentNodeIds.begin(), parentNodeIds.end());
addNodesToGraph(utility::toVector(allNodeIds), graph);
addEdgesToGraph(utility::toVector(allEdgeIds), graph);
@@ -1988,7 +1992,7 @@ void PersistentStorage::addAggregationEdgesToGraph(
nodeIdsToAdd.push_back(aggregationTargetNodeId);
}
}
addNodesWithChildrenAndEdgesToGraph(nodeIdsToAdd, std::vector<Id>(), graph);
addNodesWithParentsAndEdgesToGraph(nodeIdsToAdd, std::vector<Id>(), graph);
// create aggregation edges between parents and active node
Node* sourceNode = graph->getNodeById(nodeId);
@@ -2131,23 +2135,21 @@ void PersistentStorage::buildHierarchyCache()
return Node::intToType(m_sqliteIndexStorage.getFirstById<StorageNode>(id).type);
});
Cache<Id, bool> indexedNodeCache([this](Id id){
Cache<Id, DefinitionKind> definitionKindCache([this](Id id){
StorageSymbol symbol = m_sqliteIndexStorage.getFirstById<StorageSymbol>(id);
if (symbol.id > 0)
{
return intToDefinitionKind(symbol.definitionKind) != DEFINITION_NONE;
return intToDefinitionKind(symbol.definitionKind);
}
return false;
return DEFINITION_NONE;
});
for (const StorageEdge& edge : memberEdges)
{
bool isVisible = !(nodeTypeCache.getValue(edge.sourceNodeId) & Node::NODE_NOT_VISIBLE);
bool sourceIsIndexed = indexedNodeCache.getValue(edge.sourceNodeId);
bool targetIsIndexed = indexedNodeCache.getValue(edge.targetNodeId);
bool sourceIsVisible = !(nodeTypeCache.getValue(edge.sourceNodeId) & Node::NODE_NOT_VISIBLE);
bool targetIsImplicit = definitionKindCache.getValue(edge.targetNodeId) == DEFINITION_IMPLICIT;
m_hierarchyCache.createConnection(
edge.id, edge.sourceNodeId, edge.targetNodeId, isVisible, sourceIsIndexed, targetIsIndexed);
edge.id, edge.sourceNodeId, edge.targetNodeId, sourceIsVisible, targetIsImplicit);
}
}
+2 -1
View File
@@ -108,6 +108,7 @@ public:
virtual std::shared_ptr<Graph> getGraphForAll() const;
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(const std::vector<Id>& tokenIds, bool* isActiveNamespace = nullptr) const;
virtual std::shared_ptr<Graph> getGraphForChildrenOfNodeId(Id nodeId) const;
virtual std::shared_ptr<Graph> getGraphForTrail(Id originId, Id targetId, Edge::EdgeTypeMask trailType, size_t depth) const;
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId, Id* declarationId) const;
@@ -159,7 +160,7 @@ private:
void addNodesToGraph(const std::vector<Id>& nodeIds, Graph* graph) const;
void addEdgesToGraph(const std::vector<Id>& edgeIds, Graph* graph) const;
void addNodesWithChildrenAndEdgesToGraph(
void addNodesWithParentsAndEdgesToGraph(
const std::vector<Id>& nodeIds, const std::vector<Id>& edgeIds, Graph* graph) const;
void addAggregationEdgesToGraph(const Id nodeId, const std::vector<StorageEdge>& edgesToAggregate, Graph* graph) const;
+1
View File
@@ -49,6 +49,7 @@ public:
virtual std::shared_ptr<Graph> getGraphForAll() const = 0;
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(const std::vector<Id>& tokenIds, bool* isActiveNamespace = nullptr) const = 0;
virtual std::shared_ptr<Graph> getGraphForChildrenOfNodeId(Id nodeId) const = 0;
virtual std::shared_ptr<Graph> getGraphForTrail(Id originId, Id targetId, Edge::EdgeTypeMask trailType, size_t depth) const = 0;
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId, Id* declarationId) const = 0;
@@ -165,6 +165,16 @@ std::shared_ptr<Graph> StorageAccessProxy::getGraphForActiveTokenIds(const std::
return std::make_shared<Graph>();
}
std::shared_ptr<Graph> StorageAccessProxy::getGraphForChildrenOfNodeId(Id nodeId) const
{
if (hasSubject())
{
return m_subject->getGraphForChildrenOfNodeId(nodeId);
}
return std::make_shared<Graph>();
}
std::shared_ptr<Graph> StorageAccessProxy::getGraphForTrail(Id originId, Id targetId, Edge::EdgeTypeMask trailType, size_t depth) const
{
if (hasSubject())
+1
View File
@@ -38,6 +38,7 @@ public:
virtual std::shared_ptr<Graph> getGraphForAll() const;
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(const std::vector<Id>& tokenIds, bool* isActiveNamespace = nullptr) const;
virtual std::shared_ptr<Graph> getGraphForChildrenOfNodeId(Id nodeId) const;
virtual std::shared_ptr<Graph> getGraphForTrail(Id originId, Id targetId, Edge::EdgeTypeMask trailType, size_t depth) const;
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId, Id* declarationId) const;
+1 -1
View File
@@ -140,7 +140,7 @@ void Graph::removeNode(Node* node)
}
);
if (node->getEdges().size())
if (node->getEdgeCount())
{
LOG_ERROR("Node still has edges.");
}
+56 -20
View File
@@ -125,6 +125,18 @@ Node::Node(Id id, NodeType type, NameHierarchy nameHierarchy, bool defined)
, m_defined(defined)
, m_implicit(false)
, m_explicit(false)
, m_childCount(0)
{
}
Node::Node(const Node& other)
: Token(other)
, m_type(other.m_type)
, m_nameHierarchy(other.m_nameHierarchy)
, m_defined(other.m_defined)
, m_implicit(other.m_implicit)
, m_explicit(other.m_explicit)
, m_childCount(other.m_childCount)
{
}
@@ -199,19 +211,33 @@ void Node::setExplicit(bool bExplicit)
m_explicit = bExplicit;
}
const std::vector<Edge*>& Node::getEdges() const
size_t Node::getChildCount() const
{
return m_edges;
return m_childCount;
}
void Node::setChildCount(size_t childCount)
{
m_childCount = childCount;
}
size_t Node::getEdgeCount() const
{
return m_edges.size();
}
void Node::addEdge(Edge* edge)
{
m_edges.push_back(edge);
m_edges.emplace(edge->getId(), edge);
}
void Node::removeEdge(Edge* edge)
{
m_edges.erase(find(m_edges.begin(), m_edges.end(), edge));
auto it = m_edges.find(edge->getId());
if (it != m_edges.end())
{
m_edges.erase(it);
}
}
Node* Node::getParentNode() const
@@ -246,11 +272,16 @@ Edge* Node::getMemberEdge() const
Edge* Node::findEdge(std::function<bool(Edge*)> func) const
{
std::vector<Edge*>::const_iterator it = find_if(m_edges.begin(), m_edges.end(), func);
auto it = find_if(m_edges.begin(), m_edges.end(),
[func](std::pair<Id, Edge*> p)
{
return func(p.second);
}
);
if (it != m_edges.end())
{
return *it;
return it->second;
}
return nullptr;
@@ -263,12 +294,12 @@ Edge* Node::findEdgeOfType(Edge::EdgeTypeMask mask) const
Edge* Node::findEdgeOfType(Edge::EdgeTypeMask mask, std::function<bool(Edge*)> func) const
{
std::vector<Edge*>::const_iterator it = find_if(m_edges.begin(), m_edges.end(),
[mask, func](Edge* e)
auto it = find_if(m_edges.begin(), m_edges.end(),
[mask, func](std::pair<Id, Edge*> p)
{
if (e->isType(mask))
if (p.second->isType(mask))
{
return func(e);
return func(p.second);
}
return false;
}
@@ -276,7 +307,7 @@ Edge* Node::findEdgeOfType(Edge::EdgeTypeMask mask, std::function<bool(Edge*)> f
if (it != m_edges.end())
{
return *it;
return it->second;
}
return nullptr;
@@ -284,12 +315,12 @@ Edge* Node::findEdgeOfType(Edge::EdgeTypeMask mask, std::function<bool(Edge*)> f
Node* Node::findChildNode(std::function<bool(Node*)> func) const
{
std::vector<Edge*>::const_iterator it = find_if(m_edges.begin(), m_edges.end(),
[&func](Edge* e)
auto it = find_if(m_edges.begin(), m_edges.end(),
[&func](std::pair<Id, Edge*> p)
{
if (e->getType() == Edge::EDGE_MEMBER)
if (p.second->getType() == Edge::EDGE_MEMBER)
{
return func(e->getTo());
return func(p.second->getTo());
}
return false;
}
@@ -297,7 +328,7 @@ Node* Node::findChildNode(std::function<bool(Node*)> func) const
if (it != m_edges.end())
{
return (*it)->getTo();
return it->second->getTo();
}
return nullptr;
@@ -305,17 +336,22 @@ Node* Node::findChildNode(std::function<bool(Node*)> func) const
void Node::forEachEdge(std::function<void(Edge*)> func) const
{
for_each(m_edges.begin(), m_edges.end(), func);
for_each(m_edges.begin(), m_edges.end(),
[func](std::pair<Id, Edge*> p)
{
func(p.second);
}
);
}
void Node::forEachEdgeOfType(Edge::EdgeTypeMask mask, std::function<void(Edge*)> func) const
{
for_each(m_edges.begin(), m_edges.end(),
[mask, func](Edge* e)
[mask, func](std::pair<Id, Edge*> p)
{
if (e->isType(mask))
if (p.second->isType(mask))
{
func(e);
func(p.second);
}
}
);
+9 -3
View File
@@ -3,8 +3,8 @@
#include <algorithm>
#include <functional>
#include <map>
#include <string>
#include <vector>
#include "data/graph/Edge.h"
#include "data/graph/Token.h"
@@ -58,6 +58,7 @@ public:
static const NodeTypeMask NODE_USEABLE_TYPE;
Node(Id id, NodeType type, NameHierarchy nameHierarchy, bool defined);
Node(const Node& other);
virtual ~Node();
NodeType getType() const;
@@ -77,7 +78,10 @@ public:
bool isExplicit() const;
void setExplicit(bool bExplicit);
const std::vector<Edge*>& getEdges() const;
size_t getChildCount() const;
void setChildCount(size_t childCount);
size_t getEdgeCount() const;
void addEdge(Edge* edge);
void removeEdge(Edge* edge);
@@ -115,13 +119,15 @@ public:
private:
void operator=(const Node&);
std::vector<Edge*> m_edges;
std::map<Id, Edge*> m_edges;
NodeType m_type;
NameHierarchy m_nameHierarchy;
bool m_defined;
bool m_implicit;
bool m_explicit;
size_t m_childCount;
};
std::ostream& operator<<(std::ostream& ostream, const Node& node);