data: retrieving multiple datums with single queries
* getting all incoming and outgogin edges to children at once in aggregation edge computation * getting all edges connected to active node at once * getting all access components for all member edges at once.
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
#include "data/graph/Node.h"
|
||||
#include "data/location/TokenLocation.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utility.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
SqliteStorage::SqliteStorage(const std::string& dbFilePath)
|
||||
{
|
||||
@@ -240,52 +242,27 @@ StorageEdge SqliteStorage::getEdgeBySourceTargetType(Id sourceId, Id targetId, i
|
||||
|
||||
std::vector<StorageEdge> SqliteStorage::getEdgesBySourceId(Id sourceId) const
|
||||
{
|
||||
std::vector<StorageEdge> edges;
|
||||
return getAllEdges("WHERE source_node_id == " + std::to_string(sourceId));
|
||||
}
|
||||
|
||||
CppSQLite3Query q = m_database.execQuery((
|
||||
"SELECT id, type, target_node_id FROM edge WHERE "
|
||||
"source_node_id == " + std::to_string(sourceId) + ";"
|
||||
).c_str());
|
||||
|
||||
while (!q.eof())
|
||||
{
|
||||
const Id id = q.getIntField(0, 0);
|
||||
const int type = q.getIntField(1, -1);
|
||||
const Id targetId = q.getIntField(2, 0);
|
||||
|
||||
if (id != 0 && type != -1 && targetId != 0)
|
||||
{
|
||||
edges.push_back(StorageEdge(id, type, sourceId, targetId));
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
}
|
||||
return edges;
|
||||
std::vector<StorageEdge> SqliteStorage::getEdgesBySourceIds(const std::vector<Id>& sourceIds) const
|
||||
{
|
||||
return getAllEdges("WHERE source_node_id IN (" + utility::join(utility::toStrings(sourceIds), ',') + ")");
|
||||
}
|
||||
|
||||
std::vector<StorageEdge> SqliteStorage::getEdgesByTargetId(Id targetId) const
|
||||
{
|
||||
std::vector<StorageEdge> edges;
|
||||
return getAllEdges("WHERE target_node_id == " + std::to_string(targetId));
|
||||
}
|
||||
|
||||
CppSQLite3Query q = m_database.execQuery((
|
||||
"SELECT id, type, source_node_id FROM edge WHERE "
|
||||
"target_node_id == " + std::to_string(targetId) + ";"
|
||||
).c_str());
|
||||
std::vector<StorageEdge> SqliteStorage::getEdgesByTargetIds(const std::vector<Id>& targetIds) const
|
||||
{
|
||||
return getAllEdges("WHERE target_node_id IN (" + utility::join(utility::toStrings(targetIds), ',') + ")");
|
||||
}
|
||||
|
||||
while (!q.eof())
|
||||
{
|
||||
const Id id = q.getIntField(0, 0);
|
||||
const int type = q.getIntField(1, -1);
|
||||
const Id sourceId = q.getIntField(2, 0);
|
||||
|
||||
if (id != 0 && type != -1 && targetId != 0)
|
||||
{
|
||||
edges.push_back(StorageEdge(id, type, sourceId, targetId));
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
}
|
||||
return edges;
|
||||
std::vector<StorageEdge> SqliteStorage::getEdgesBySourceOrTargetId(Id id) const
|
||||
{
|
||||
return getAllEdges("WHERE source_node_id == " + std::to_string(id) + " OR target_node_id == " + std::to_string(id));
|
||||
}
|
||||
|
||||
std::vector<StorageEdge> SqliteStorage::getEdgesBySourceType(Id sourceId, int type) const
|
||||
@@ -626,13 +603,31 @@ StorageComponentAccess SqliteStorage::getComponentAccessByMemberEdgeId(Id member
|
||||
while (!q.eof())
|
||||
{
|
||||
return StorageComponentAccess(
|
||||
q.getIntField(0, 0),
|
||||
q.getIntField(1, 0),
|
||||
q.getIntField(2, 0)
|
||||
);
|
||||
}
|
||||
|
||||
return StorageComponentAccess(0, 0, 0);
|
||||
return StorageComponentAccess(0, 0);
|
||||
}
|
||||
|
||||
std::vector<StorageComponentAccess> SqliteStorage::getComponentAccessByMemberEdgeIds(const std::vector<Id>& memberEdgeIds) const
|
||||
{
|
||||
CppSQLite3Query q = m_database.execQuery((
|
||||
"SELECT id, edge_id, type FROM component_access WHERE edge_id IN (" + utility::join(utility::toStrings(memberEdgeIds), ',') + ");"
|
||||
).c_str());
|
||||
|
||||
std::vector<StorageComponentAccess> accesses;
|
||||
while (!q.eof())
|
||||
{
|
||||
accesses.push_back(StorageComponentAccess(
|
||||
q.getIntField(1, 0),
|
||||
q.getIntField(2, 0)
|
||||
));
|
||||
|
||||
q.nextRow();
|
||||
}
|
||||
return accesses;
|
||||
}
|
||||
|
||||
Id SqliteStorage::getNodeIdBySignature(const std::string& signature) const
|
||||
@@ -854,3 +849,27 @@ std::vector<StorageSourceLocation> SqliteStorage::getAllSourceLocations(const st
|
||||
|
||||
return sourceLocations;
|
||||
}
|
||||
|
||||
std::vector<StorageEdge> SqliteStorage::getAllEdges(const std::string& query) const
|
||||
{
|
||||
CppSQLite3Query q = m_database.execQuery((
|
||||
"SELECT id, type, source_node_id, target_node_id FROM edge " + query + ";"
|
||||
).c_str());
|
||||
|
||||
std::vector<StorageEdge> edges;
|
||||
while (!q.eof())
|
||||
{
|
||||
const Id id = q.getIntField(0, 0);
|
||||
const int type = q.getIntField(1, -1);
|
||||
const Id sourceId = q.getIntField(2, 0);
|
||||
const Id targetId = q.getIntField(3, 0);
|
||||
|
||||
if (id != 0 && type != -1)
|
||||
{
|
||||
edges.push_back(StorageEdge(id, type, sourceId, targetId));
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,10 @@ public:
|
||||
|
||||
StorageEdge getEdgeBySourceTargetType(Id sourceId, Id targetId, int type) const;
|
||||
std::vector<StorageEdge> getEdgesBySourceId(Id sourceId) const;
|
||||
std::vector<StorageEdge> getEdgesBySourceIds(const std::vector<Id>& sourceIds) const;
|
||||
std::vector<StorageEdge> getEdgesByTargetId(Id targetId) const;
|
||||
std::vector<StorageEdge> getEdgesByTargetIds(const std::vector<Id>& targetIds) const;
|
||||
std::vector<StorageEdge> getEdgesBySourceOrTargetId(Id id) const;
|
||||
std::vector<StorageEdge> getEdgesBySourceType(Id sourceId, int type) const;
|
||||
std::vector<StorageEdge> getEdgesByTargetType(Id targetId, int type) const;
|
||||
StorageEdge getEdgeById(Id edgeId) const;
|
||||
@@ -81,6 +84,7 @@ public:
|
||||
Id getElementIdByLocationId(Id locationId) const;
|
||||
|
||||
StorageComponentAccess getComponentAccessByMemberEdgeId(Id memberEdgeId) const;
|
||||
std::vector<StorageComponentAccess> getComponentAccessByMemberEdgeIds(const std::vector<Id>& memberEdgeIds) const;
|
||||
Id getNodeIdBySignature(const std::string& signature) const;
|
||||
|
||||
int getNodeCount() const;
|
||||
@@ -96,6 +100,8 @@ private:
|
||||
StorageSourceLocation getFirstSourceLocation(const std::string& query) const;
|
||||
std::vector<StorageSourceLocation> getAllSourceLocations(const std::string& query) const;
|
||||
|
||||
std::vector<StorageEdge> getAllEdges(const std::string& query) const;
|
||||
|
||||
template <typename ResultType>
|
||||
ResultType getFirstResult(const std::string& query) const;
|
||||
|
||||
|
||||
+49
-45
@@ -722,8 +722,7 @@ std::shared_ptr<Graph> Storage::getGraphForActiveTokenIds(const std::vector<Id>&
|
||||
);
|
||||
std::cout << "add node and children " << a << std::endl;
|
||||
|
||||
std::vector<StorageEdge> edges = m_sqliteStorage.getEdgesBySourceId(node.id);
|
||||
utility::append(edges, m_sqliteStorage.getEdgesByTargetId(node.id));
|
||||
std::vector<StorageEdge> edges = m_sqliteStorage.getEdgesBySourceOrTargetId(node.id);
|
||||
|
||||
float b = utility::duration(
|
||||
[&]()
|
||||
@@ -771,21 +770,7 @@ std::shared_ptr<Graph> Storage::getGraphForActiveTokenIds(const std::vector<Id>&
|
||||
}
|
||||
}
|
||||
|
||||
graph->forEachEdge(
|
||||
[this](Edge* edge)
|
||||
{
|
||||
if (!edge->isType(Edge::EDGE_MEMBER))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StorageComponentAccess access = m_sqliteStorage.getComponentAccessByMemberEdgeId(edge->getId());
|
||||
if (access.id && access.type)
|
||||
{
|
||||
edge->addComponentAccess(std::make_shared<TokenComponentAccess>(TokenComponentAccess::intToType(access.type)));
|
||||
}
|
||||
}
|
||||
);
|
||||
addComponentAccessToGraph(graph);
|
||||
|
||||
return g;
|
||||
}
|
||||
@@ -1355,39 +1340,30 @@ void Storage::addAggregationEdgesToGraph(const Id nodeId, Graph* graph) const
|
||||
|
||||
// build aggregation edges:
|
||||
// get all children of the active node
|
||||
// get all edges of the children
|
||||
// get all nodes connected by these edges
|
||||
// remove all nodes that are in active node's children
|
||||
// get all parents of these nodes (up to last level except namespace/undefined)
|
||||
// add hierarchies for these parents
|
||||
// create aggregation edges between parents and active node
|
||||
|
||||
std::vector<Id> childNodeIds = getAllChildNodeIds(nodeId, graph);
|
||||
|
||||
// get all edges of the children
|
||||
std::map<Id, std::vector<EdgeInfo>> connectedNodeIds;
|
||||
for (size_t i = 0; i < childNodeIds.size(); i++)
|
||||
|
||||
std::vector<StorageEdge> outgoingEdges = m_sqliteStorage.getEdgesBySourceIds(childNodeIds);
|
||||
for (size_t j = 0; j < outgoingEdges.size(); j++)
|
||||
{
|
||||
const Id nodeId = childNodeIds[i];
|
||||
|
||||
std::vector<StorageEdge> outgoingEdges = m_sqliteStorage.getEdgesBySourceId(nodeId);
|
||||
for (size_t j = 0; j < outgoingEdges.size(); j++)
|
||||
{
|
||||
EdgeInfo edgeInfo;
|
||||
edgeInfo.edgeId = outgoingEdges[j].id;
|
||||
edgeInfo.forward = true;
|
||||
connectedNodeIds[outgoingEdges[j].targetNodeId].push_back(edgeInfo);
|
||||
}
|
||||
|
||||
std::vector<StorageEdge> incomingEdges = m_sqliteStorage.getEdgesByTargetId(nodeId);
|
||||
for (size_t j = 0; j < incomingEdges.size(); j++)
|
||||
{
|
||||
EdgeInfo edgeInfo;
|
||||
edgeInfo.edgeId = incomingEdges[j].id;
|
||||
edgeInfo.forward = false;
|
||||
connectedNodeIds[incomingEdges[j].sourceNodeId].push_back(edgeInfo);
|
||||
}
|
||||
EdgeInfo edgeInfo;
|
||||
edgeInfo.edgeId = outgoingEdges[j].id;
|
||||
edgeInfo.forward = true;
|
||||
connectedNodeIds[outgoingEdges[j].targetNodeId].push_back(edgeInfo);
|
||||
}
|
||||
|
||||
std::vector<StorageEdge> incomingEdges = m_sqliteStorage.getEdgesByTargetIds(childNodeIds);
|
||||
for (size_t j = 0; j < incomingEdges.size(); j++)
|
||||
{
|
||||
EdgeInfo edgeInfo;
|
||||
edgeInfo.edgeId = incomingEdges[j].id;
|
||||
edgeInfo.forward = false;
|
||||
connectedNodeIds[incomingEdges[j].sourceNodeId].push_back(edgeInfo);
|
||||
}
|
||||
|
||||
// get all parent nodes of all connected nodes (up to last level except namespace/undefined)
|
||||
Id nodeParentNodeId = getLastVisibleParentNodeId(nodeId);
|
||||
|
||||
std::map<Id, std::vector<EdgeInfo>> connectedParentNodeIds;
|
||||
@@ -1401,6 +1377,7 @@ void Storage::addAggregationEdgesToGraph(const Id nodeId, Graph* graph) const
|
||||
}
|
||||
}
|
||||
|
||||
// add hierarchies for these parents and create aggregation edges between parents and active node
|
||||
Node* sourceNode = graph->getNodeById(nodeId);
|
||||
|
||||
for (const std::pair<Id, std::vector<EdgeInfo>> p : connectedParentNodeIds)
|
||||
@@ -1410,7 +1387,7 @@ void Storage::addAggregationEdgesToGraph(const Id nodeId, Graph* graph) const
|
||||
Node* targetNode = graph->getNodeById(aggregationTargetNodeId);
|
||||
if (!targetNode)
|
||||
{
|
||||
targetNode = addNodeAndAllChildrenToGraph(getLastVisibleParentNodeId(aggregationTargetNodeId), graph);
|
||||
targetNode = addNodeAndAllChildrenToGraph(aggregationTargetNodeId, graph);
|
||||
}
|
||||
|
||||
std::shared_ptr<TokenComponentAggregation> componentAggregation = std::make_shared<TokenComponentAggregation>();
|
||||
@@ -1479,3 +1456,30 @@ void Storage::addAccess(const Id nodeId, ParserClient::AccessType access)
|
||||
|
||||
m_sqliteStorage.addComponentAccess(memberEdges[0].id, convertAccessType(access));
|
||||
}
|
||||
|
||||
void Storage::addComponentAccessToGraph(Graph* graph) const
|
||||
{
|
||||
std::vector<Id> memberEdgeIds;
|
||||
|
||||
graph->forEachEdge(
|
||||
[&memberEdgeIds](Edge* edge)
|
||||
{
|
||||
if (!edge->isType(Edge::EDGE_MEMBER))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memberEdgeIds.push_back(edge->getId());
|
||||
}
|
||||
);
|
||||
|
||||
std::vector<StorageComponentAccess> accesses = m_sqliteStorage.getComponentAccessByMemberEdgeIds(memberEdgeIds);
|
||||
for (const StorageComponentAccess& access : accesses)
|
||||
{
|
||||
if (access.memberEdgeId && access.type)
|
||||
{
|
||||
graph->getEdgeById(access.memberEdgeId)->addComponentAccess(
|
||||
std::make_shared<TokenComponentAccess>(TokenComponentAccess::intToType(access.type)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,6 +174,8 @@ private:
|
||||
TokenComponentAccess::AccessType convertAccessType(ParserClient::AccessType access) const;
|
||||
void addAccess(const Id nodeId, ParserClient::AccessType access);
|
||||
|
||||
void addComponentAccessToGraph(Graph* graph) const;
|
||||
|
||||
SearchIndex m_tokenIndex;
|
||||
SqliteStorage m_sqliteStorage;
|
||||
|
||||
|
||||
@@ -70,13 +70,11 @@ struct StorageSourceLocation
|
||||
|
||||
struct StorageComponentAccess
|
||||
{
|
||||
StorageComponentAccess(Id id, Id memberEdgeId, int type)
|
||||
: id(id)
|
||||
, memberEdgeId(memberEdgeId)
|
||||
StorageComponentAccess(Id memberEdgeId, int type)
|
||||
: memberEdgeId(memberEdgeId)
|
||||
, type(type)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
Id memberEdgeId;
|
||||
int type;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user