public bool TryGetNode(string key, out MatchNode node) { foreach (var subGraph in ConnectedSubGraphs) { if (subGraph.Nodes.TryGetValue(key, out node)) { return(true); } } node = null; return(false); }
public string GetNodeRefName(MatchNode node) { int count = MaterializedNodeSplitCount[node]; if (count == 0) { return(node.RefAlias); } else { return(string.Format("{0}_{1}", node.RefAlias, count)); } }
public MatchComponent(MatchNode node) : this() { Nodes.Add(node.NodeAlias, node); MaterializedNodeSplitCount[node] = 0; //SinkNodeStatisticsDict[node] = new Statistics (); NodeToMaterializedEdgesDict[node.NodeAlias] = new List <Tuple <MatchEdge, MaterializedEdgeType> >(); Cardinality *= node.EstimatedRows; foreach (var edge in node.Neighbors) { var edgeList = UnmaterializedNodeMapping.GetOrCreate(edge.SinkNode); edgeList.Add(edge); } }
public MatchNode(MatchNode rhs) { this.NodeAlias = rhs.NodeAlias; this.NodeTableObjectName = rhs.NodeTableObjectName; this.Neighbors = rhs.Neighbors; this.ReverseNeighbors = rhs.ReverseNeighbors; this.DanglingEdges = rhs.DanglingEdges; this.EstimatedRows = rhs.EstimatedRows; this.TableRowCount = rhs.TableRowCount; this.AttachedJsonQuery = rhs.AttachedJsonQuery; this.Properties = new HashSet <string>(rhs.Properties); this.GlobalNodeIdDensity = rhs.GlobalNodeIdDensity; this.Predicates = rhs.Predicates; }
public MatchComponent(MatchNode node, List <MatchEdge> populatedEdges, WSqlTableContext context) : this(node) { Context = context; foreach (var edge in populatedEdges) { TableRef = SpanTableRef(TableRef, edge, node.RefAlias); EdgeMaterilizedDict[edge] = true; StatisticsDict[edge.SinkNode] = Context.GetEdgeStatistics(edge); var edgeList = UnmaterializedNodeMapping.GetOrCreate(edge.SinkNode); edgeList.Add(edge); Nodes.Add(edge.SinkNode); Size *= edge.AverageDegree; EstimateSize *= 1000; } }
public MatchComponent(MatchNode node) : this() { Nodes.Add(node); MaterializedNodeSplitCount[node] = 0; //SinkNodeStatisticsDict[node] = new Statistics (); Cardinality *= node.EstimatedRows; SqlEstimatedSize *= node.EstimatedRows; TableRef = new WNamedTableReference { Alias = new Identifier { Value = node.RefAlias }, TableObjectName = node.NodeTableObjectName }; }
public override bool Equals(object obj) { if (Object.ReferenceEquals(this, obj)) { return(true); } MatchNode rhs = obj as MatchNode; if (rhs == null) { return(false); } return(this.NodeAlias.Equals(rhs.NodeAlias)); }
public MatchComponent(MatchNode node, List <MatchEdge> populatedEdges, GraphMetaData metaData) : this(node) { foreach (var edge in populatedEdges) { TableRef = SpanTableRef(TableRef, edge, node.RefAlias, metaData); EdgeMaterilizedDict[edge] = true; SinkNodeStatisticsDict[edge.SinkNode] = edge.Statistics; var edgeList = UnmaterializedNodeMapping.GetOrCreate(edge.SinkNode); edgeList.Add(edge); if (!Nodes.Contains(edge.SinkNode)) { Nodes.Add(edge.SinkNode); } Cardinality *= edge.AverageDegree; SqlEstimatedSize *= 1000; } }
public MatchComponent(MatchNode node) : this() { Nodes.Add(node); MaterializedNodeSplitCount[node] = 0; StatisticsDict[node] = new ColumnStatistics { Selectivity = 1.0 / node.TableRowCount }; Size *= node.EstimatedRows; EstimateSize *= node.EstimatedRows; TableRef = new WNamedTableReference { Alias = new Identifier { Value = node.RefAlias }, TableObjectName = node.TableObjectName }; }
public LinkQuery(Dictionary <string, int> GraphDescription, MatchNode Src, MatchNode Dest, string EdgeAlias) { SrcNum = GraphDescription[Src.NodeAlias]; SrcAlias = Src.NodeAlias; SrcSelectClause = Src.DocDBQuery.Replace("'", "\""); DestNum = GraphDescription[Dest.NodeAlias]; DestAlias = Dest.NodeAlias; DestSelectClause = Dest.DocDBQuery.Replace("'", "\""); EdgeSpecifier = EdgeAlias; EdgeList = new List <string>(); foreach (var EdgeToNeighbor in Src.Neighbors) { if (EdgeToNeighbor.SinkNode.NodeAlias == DestAlias) { EdgeList.Add(EdgeToNeighbor.EdgeAlias); } } }
// We firstly think every node are isolated, and we will find subgraphs later internal string AddTable(WNamedTableReference table) { string alias = table.Alias.Value; this.TableInputDependency[alias] = new HashSet <string>(); MatchNode matchNode = new MatchNode() { NodeAlias = alias, Neighbors = new List <MatchEdge>(), ReverseNeighbors = new List <MatchEdge>(), DanglingEdges = new List <MatchEdge>(), Predicates = new List <WBooleanExpression>(), Properties = new HashSet <string>() }; ConnectedComponent subgraph = new ConnectedComponent(); subgraph.Nodes[alias] = matchNode; this.GraphPattern.ConnectedSubgraphs.Add(subgraph); matchNode.Position = this.TableInputDependency.Count; return(alias); }
/// <summary> /// Item1: current node. A query will be sent to the server to fetch this node if this is the first time it appears in the whole list. /// Item2: the traversalEdge whose sink is current node. /// Item3: traversalEdges whose source is currentNode. /// This list will either contain 0 or 1 traversal edge in the current version, and it will be pushed to server if possible. /// Item4: backwardMatchingEdges. /// Item5: forwardMatchingEdges. /// </summary> /// <param name="traversalChain"></param> /// <returns></returns> protected List <Tuple <MatchNode, MatchEdge, List <MatchEdge>, List <MatchEdge>, List <MatchEdge> > > GenerateTraversalOrderFromTraversalChain (List <Tuple <MatchNode, MatchEdge, MatchNode, List <MatchEdge>, List <MatchEdge> > > traversalChain) { Dictionary <string, int> nodeFetchingOrderDict = new Dictionary <string, int>(); List <Tuple <MatchNode, MatchEdge, List <MatchEdge>, List <MatchEdge>, List <MatchEdge> > > optimizedTraversalOrder = new List <Tuple <MatchNode, MatchEdge, List <MatchEdge>, List <MatchEdge>, List <MatchEdge> > >(); foreach (Tuple <MatchNode, MatchEdge, MatchNode, List <MatchEdge>, List <MatchEdge> > tuple in traversalChain) { MatchNode srcNode = tuple.Item1; MatchEdge traversalEdge = tuple.Item2; int nodeFetchingOrder; if (nodeFetchingOrderDict.TryGetValue(srcNode.NodeAlias, out nodeFetchingOrder)) { List <MatchEdge> traversalEdges = optimizedTraversalOrder[nodeFetchingOrder].Item3; if (traversalEdges.Count == 0) { traversalEdges.Add(traversalEdge); } else { optimizedTraversalOrder.Add( new Tuple <MatchNode, MatchEdge, List <MatchEdge>, List <MatchEdge>, List <MatchEdge> >( srcNode, null, new List <MatchEdge> { traversalEdge }, new List <MatchEdge>(), new List <MatchEdge>())); } } else { nodeFetchingOrderDict.Add(srcNode.NodeAlias, optimizedTraversalOrder.Count); optimizedTraversalOrder.Add( new Tuple <MatchNode, MatchEdge, List <MatchEdge>, List <MatchEdge>, List <MatchEdge> >( srcNode, null, traversalEdge != null ? new List <MatchEdge> { traversalEdge } : new List <MatchEdge>(), new List <MatchEdge>(), new List <MatchEdge>())); } if (traversalEdge != null) { MatchNode sinkNode = tuple.Item3; List <MatchEdge> backwardEdges = tuple.Item4; List <MatchEdge> forwardEdges = tuple.Item5; nodeFetchingOrderDict.Add(sinkNode.NodeAlias, optimizedTraversalOrder.Count); optimizedTraversalOrder.Add( new Tuple <MatchNode, MatchEdge, List <MatchEdge>, List <MatchEdge>, List <MatchEdge> >( sinkNode, traversalEdge, new List <MatchEdge>(), backwardEdges, forwardEdges)); } } return(optimizedTraversalOrder); }
public string GetNodeRefName(MatchNode node) { int count = MaterializedNodeSplitCount[node]; if (count == 0) return node.RefAlias; else return string.Format("{0}_{1}", node.RefAlias, count); }
// Greate the MatchGraph of this AggregationBlock. If some free nodes and free edges are connected, they are in the same ConnectedComponent internal HashSet <string> CreateMatchGraph(WMatchClause matchClause) { HashSet <string> freeNodesAndEdges = new HashSet <string>(); Dictionary <string, MatchPath> pathCollection = new Dictionary <string, MatchPath>(StringComparer.OrdinalIgnoreCase); Dictionary <string, MatchNode> nodeCollection = new Dictionary <string, MatchNode>(StringComparer.OrdinalIgnoreCase); Dictionary <string, MatchEdge> edgeCollection = new Dictionary <string, MatchEdge>(StringComparer.OrdinalIgnoreCase); Dictionary <string, ConnectedComponent> subgraphCollection = new Dictionary <string, ConnectedComponent>(StringComparer.OrdinalIgnoreCase); // we use Disjoint-set data structure to determine whether tables are in the same component or not. UnionFind unionFind = new UnionFind(); foreach (ConnectedComponent subgraph in this.GraphPattern.ConnectedSubgraphs) { foreach (KeyValuePair <string, MatchNode> pair in subgraph.Nodes) { nodeCollection.Add(pair.Key, pair.Value); unionFind.Add(pair.Key); } } if (matchClause != null) { foreach (WMatchPath path in matchClause.Paths) { int index = 0; bool outOfBlock = false; MatchEdge edgeToSrcNode = null; for (int count = path.PathEdgeList.Count; index < count; ++index) { WSchemaObjectName currentNodeTableRef = path.PathEdgeList[index].Item1; WEdgeColumnReferenceExpression currentEdgeColumnRef = path.PathEdgeList[index].Item2; WSchemaObjectName nextNodeTableRef = index != count - 1 ? path.PathEdgeList[index + 1].Item1 : path.Tail; string currentNodeExposedName = currentNodeTableRef.BaseIdentifier.Value; string edgeAlias = currentEdgeColumnRef.Alias; string nextNodeExposedName = nextNodeTableRef != null ? nextNodeTableRef.BaseIdentifier.Value : null; // Get the source node of a path if (!nodeCollection.ContainsKey(currentNodeExposedName)) { continue; } MatchNode srcNode = nodeCollection[currentNodeExposedName]; // Get the edge of a path, and set required attributes // Because the sourceNode is relative, we need to construct new edges or paths // But they need to share the same predicates and proerties MatchEdge edgeFromSrcNode; if (currentEdgeColumnRef.MinLength == 1 && currentEdgeColumnRef.MaxLength == 1) { if (!edgeCollection.ContainsKey(edgeAlias)) { edgeCollection[edgeAlias] = new MatchEdge() { LinkAlias = edgeAlias, SourceNode = srcNode, EdgeType = currentEdgeColumnRef.EdgeType, Predicates = new List <WBooleanExpression>(), BindNodeTableObjName = new WSchemaObjectName(), IsReversed = false, Properties = new List <string>(GraphViewReservedProperties.ReservedEdgeProperties) }; unionFind.Add(edgeAlias); } edgeFromSrcNode = new MatchEdge { LinkAlias = edgeAlias, SourceNode = srcNode, EdgeType = edgeCollection[edgeAlias].EdgeType, Predicates = edgeCollection[edgeAlias].Predicates, BindNodeTableObjName = edgeCollection[edgeAlias].BindNodeTableObjName, IsReversed = false, Properties = edgeCollection[edgeAlias].Properties }; } else { if (!pathCollection.ContainsKey(edgeAlias)) { pathCollection[edgeAlias] = new MatchPath { SourceNode = srcNode, LinkAlias = edgeAlias, Predicates = new List <WBooleanExpression>(), BindNodeTableObjName = new WSchemaObjectName(), MinLength = currentEdgeColumnRef.MinLength, MaxLength = currentEdgeColumnRef.MaxLength, ReferencePathInfo = false, AttributeValueDict = currentEdgeColumnRef.AttributeValueDict, IsReversed = false, EdgeType = currentEdgeColumnRef.EdgeType, Properties = new List <string>(GraphViewReservedProperties.ReservedEdgeProperties) }; } edgeFromSrcNode = new MatchPath { SourceNode = srcNode, LinkAlias = edgeAlias, Predicates = pathCollection[edgeAlias].Predicates, BindNodeTableObjName = pathCollection[edgeAlias].BindNodeTableObjName, MinLength = pathCollection[edgeAlias].MinLength, MaxLength = pathCollection[edgeAlias].MaxLength, ReferencePathInfo = false, AttributeValueDict = pathCollection[edgeAlias].AttributeValueDict, IsReversed = false, EdgeType = pathCollection[edgeAlias].EdgeType, Properties = pathCollection[edgeAlias].Properties }; } if (path.IsReversed) { unionFind.Union(edgeAlias, currentNodeExposedName); } else { unionFind.Union(currentNodeExposedName, edgeAlias); } if (edgeToSrcNode != null) { edgeToSrcNode.SinkNode = srcNode; if (!(edgeToSrcNode is MatchPath)) { // Construct reverse edge MatchEdge reverseEdge = new MatchEdge { SourceNode = edgeToSrcNode.SinkNode, SinkNode = edgeToSrcNode.SourceNode, LinkAlias = edgeToSrcNode.LinkAlias, Predicates = edgeToSrcNode.Predicates, BindNodeTableObjName = edgeToSrcNode.BindNodeTableObjName, IsReversed = true, EdgeType = edgeToSrcNode.EdgeType, Properties = edgeToSrcNode.Properties, }; srcNode.ReverseNeighbors.Add(reverseEdge); } } edgeToSrcNode = edgeFromSrcNode; // Add this edge to node's neightbors if (nextNodeExposedName != null) { if (path.IsReversed) { unionFind.Union(nextNodeExposedName, edgeAlias); } else { unionFind.Union(edgeAlias, nextNodeExposedName); } srcNode.Neighbors.Add(edgeFromSrcNode); } // Add this edge to node's dangling edges else { srcNode.DanglingEdges.Add(edgeFromSrcNode); } } if (path.Tail == null) { continue; } // Get destination node of a path string tailExposedName = path.Tail.BaseIdentifier.Value; if (!nodeCollection.ContainsKey(tailExposedName)) { continue; } MatchNode destNode = nodeCollection[tailExposedName]; if (edgeToSrcNode != null) { edgeToSrcNode.SinkNode = destNode; if (!(edgeToSrcNode is MatchPath)) { // Construct reverse edge MatchEdge reverseEdge = new MatchEdge { SourceNode = edgeToSrcNode.SinkNode, SinkNode = edgeToSrcNode.SourceNode, LinkAlias = edgeToSrcNode.LinkAlias, Predicates = edgeToSrcNode.Predicates, BindNodeTableObjName = edgeToSrcNode.BindNodeTableObjName, IsReversed = true, EdgeType = edgeToSrcNode.EdgeType, Properties = edgeToSrcNode.Properties, }; destNode.ReverseNeighbors.Add(reverseEdge); } } } } // Use union find algorithmn to define which subgraph does a node belong to and put it into where it belongs to. foreach (var node in nodeCollection) { freeNodesAndEdges.Add(node.Key); string root = unionFind.Find(node.Key); ConnectedComponent subGraph; if (!subgraphCollection.ContainsKey(root)) { subGraph = new ConnectedComponent(); subgraphCollection[root] = subGraph; } else { subGraph = subgraphCollection[root]; } subGraph.Nodes[node.Key] = node.Value; subGraph.IsTailNode[node.Value] = false; foreach (MatchEdge edge in node.Value.Neighbors) { subGraph.Edges[edge.LinkAlias] = edge; freeNodesAndEdges.Add(edge.LinkAlias); } foreach (MatchEdge edge in node.Value.DanglingEdges) { subGraph.Edges[edge.LinkAlias] = edge; edge.IsDanglingEdge = true; freeNodesAndEdges.Add(edge.LinkAlias); } if (node.Value.Neighbors.Count + node.Value.ReverseNeighbors.Count + node.Value.DanglingEdges.Count > 0) { node.Value.Properties.Add(GremlinKeyword.Star); } } this.GraphPattern = new MatchGraph(subgraphCollection.Values.ToList()); return(freeNodesAndEdges); }
/// <summary> /// Given a node / TVF, a traversalLink and backwardEdges, try to find all predicates that can be evaluated /// </summary> /// <param name="node"></param> /// <param name="traversalLink"></param> /// <param name="backwardEdges"></param> /// <param name="predicateLinksAccessedTableAliases"></param> private List <Tuple <PredicateLink, int> > FindPredicates( CompileNode node, CompileLink traversalLink, List <Tuple <MatchEdge, int> > backwardEdges, List <Tuple <PredicateLink, HashSet <string> > > predicateLinksAccessedTableAliases) { // Record temporary aliases and predicates HashSet <string> temporaryAliases = new HashSet <string>(this.ExistingNodesAndEdges); HashSet <string> temporaryPredicates = new HashSet <string>(this.ExistingPredicateLinks); List <Tuple <PredicateLink, int> > forwardLinks = new List <Tuple <PredicateLink, int> >(); // priority = 1 // retrieve traversalLink and add predicates if (traversalLink != null && !this.ExistingNodesAndEdges.Contains(traversalLink.LinkAlias)) { // Find predicates that can be evaluated after retrieving this traversalLink if (traversalLink is MatchEdge) { temporaryAliases.Add(traversalLink.LinkAlias); } else if (traversalLink is PredicateLink) { temporaryPredicates.Add(traversalLink.LinkAlias); } else { throw new QueryCompilationException("Cannot support " + traversalLink + " as a traversal link or an edge"); } foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases) { if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) && temporaryAliases.IsSupersetOf(tuple.Item2)) { temporaryPredicates.Add(tuple.Item1.LinkAlias); forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 1)); } } // Make sure the all existing edges and this traversalLink are consistent // Because all existing edges are consistent, we just need make one exstring edge and this traversalLink consistent MatchNode matchNode = node as MatchNode; WColumnReferenceExpression nodeColumnReferenceExprFromTraversalLink = GetNodeColumnReferenceExprFromLink(traversalLink); WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(matchNode, this.ExistingNodesAndEdges); if (nodeColumnReferenceExprFromTraversalLink != null && nodeColumnReferenceExprFromAnExistingEdge != null) { forwardLinks.Add( new Tuple <PredicateLink, int>( new PredicateLink( SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromTraversalLink, nodeColumnReferenceExprFromAnExistingEdge)), 1)); } } // priority = 2 // retrieve node and some edges and add predicates temporaryAliases.Add(node.NodeAlias); foreach (Tuple <MatchEdge, int> tuple in backwardEdges) { if (tuple.Item2 == 2) { temporaryAliases.Add(tuple.Item1.LinkAlias); MatchNode otherNode = tuple.Item1.SinkNode; WColumnReferenceExpression nodeColumnReferenceExprFromBackwardEdge = null; WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(otherNode, this.ExistingNodesAndEdges); if (nodeColumnReferenceExprFromAnExistingEdge != null) { foreach (MatchEdge edge in otherNode.Neighbors) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } if (nodeColumnReferenceExprFromBackwardEdge == null) { foreach (MatchEdge edge in otherNode.ReverseNeighbors) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } } if (nodeColumnReferenceExprFromBackwardEdge == null) { foreach (MatchEdge edge in otherNode.DanglingEdges) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } } } // Because all existing edges are consistent, we just need make one exstring edge and this edge consistent if (nodeColumnReferenceExprFromBackwardEdge != null && nodeColumnReferenceExprFromAnExistingEdge != null) { temporaryPredicates.Add(tuple.Item1.LinkAlias); forwardLinks.Add( new Tuple <PredicateLink, int>( new PredicateLink( SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromBackwardEdge, nodeColumnReferenceExprFromAnExistingEdge)), 2)); } } } // Check predicates foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases) { if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) && temporaryAliases.IsSupersetOf(tuple.Item2)) { temporaryPredicates.Add(tuple.Item1.LinkAlias); forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 2)); } } // priority = 3 // retrieve another edges and add predicates foreach (Tuple <MatchEdge, int> tuple in backwardEdges) { if (tuple.Item2 == 3) { temporaryAliases.Add(tuple.Item1.LinkAlias); MatchNode otherNode = tuple.Item1.SinkNode; WColumnReferenceExpression nodeColumnReferenceExprFromBackwardEdge = null; WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(otherNode, this.ExistingNodesAndEdges); if (nodeColumnReferenceExprFromAnExistingEdge != null) { foreach (MatchEdge edge in otherNode.Neighbors) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } if (nodeColumnReferenceExprFromBackwardEdge == null) { foreach (MatchEdge edge in otherNode.ReverseNeighbors) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } } if (nodeColumnReferenceExprFromBackwardEdge == null) { foreach (MatchEdge edge in otherNode.DanglingEdges) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } } } // Because all existing edges are consistent, we just need make one exstring edge and this edge consistent if (nodeColumnReferenceExprFromBackwardEdge != null && nodeColumnReferenceExprFromAnExistingEdge != null) { temporaryPredicates.Add(tuple.Item1.LinkAlias); forwardLinks.Add( new Tuple <PredicateLink, int>( new PredicateLink( SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromBackwardEdge, nodeColumnReferenceExprFromAnExistingEdge)), 3)); } } } // Check predicates foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases) { if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) && temporaryAliases.IsSupersetOf(tuple.Item2)) { temporaryPredicates.Add(tuple.Item1.LinkAlias); forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 3)); } } return(forwardLinks); }
private void UpdateComponent(MatchComponent curComponent, CandidateJoinUnit candidateTree) { Dictionary <string, MatchNode> nodes = curComponent.Nodes; Dictionary <MatchEdge, bool> edgeMaterializedDict = curComponent.EdgeMaterilizedDict; Dictionary <MatchNode, List <MatchEdge> > unmaterializedNodeMapping = curComponent.UnmaterializedNodeMapping; MatchNode root = candidateTree.TreeRoot; if (!nodes.ContainsKey(root.NodeAlias)) { nodes.Add(root.NodeAlias, new MatchNode(root)); } curComponent.MaterializedNodeSplitCount[root] = 0; List <Tuple <MaterializedOrder, MatchEdge> > inEdges = candidateTree.PreMatIncomingEdges.Select( e => new Tuple <MaterializedOrder, MatchEdge>(MaterializedOrder.Pre, e)) .Union( candidateTree.PostMatIncomingEdges.Select( e => new Tuple <MaterializedOrder, MatchEdge>(MaterializedOrder.Post, e))) .ToList(); List <Tuple <MaterializedOrder, MatchEdge> > outEdges = candidateTree.PreMatOutgoingEdges.Select( e => new Tuple <MaterializedOrder, MatchEdge>(MaterializedOrder.Pre, e)) .Union( candidateTree.PostMatOutgoingEdges.Select( e => new Tuple <MaterializedOrder, MatchEdge>(MaterializedOrder.Post, e))) .ToList(); if (inEdges.Any()) { unmaterializedNodeMapping.Remove(root); foreach (Tuple <MaterializedOrder, MatchEdge> t in inEdges) { MaterializedOrder order = t.Item1; MatchEdge edge = t.Item2; edgeMaterializedDict[edge] = true; List <string> adjListProperties = this.PopulateAdjacencyListProperties(edge); MatchNode node = curComponent.Nodes[edge.SourceNode.NodeAlias]; foreach (string adjListProperty in adjListProperties) { node.Properties.Add(adjListProperty); } } } if (outEdges.Any()) { foreach (Tuple <MaterializedOrder, MatchEdge> t in outEdges) { MaterializedOrder order = t.Item1; MatchEdge edge = t.Item2; edgeMaterializedDict[edge] = true; List <string> adjListProperties = this.PopulateAdjacencyListProperties(edge); MatchNode node = curComponent.Nodes[edge.SourceNode.NodeAlias]; foreach (string adjListProperty in adjListProperties) { node.Properties.Add(adjListProperty); } } } List <MatchEdge> unmatEdges = candidateTree.UnmaterializedEdges; foreach (MatchEdge unmatEdge in unmatEdges) { edgeMaterializedDict[unmatEdge] = false;; List <MatchEdge> unmatNodeInEdges = unmaterializedNodeMapping.GetOrCreate(unmatEdge.SinkNode); unmatNodeInEdges.Add(unmatEdge); } }
public MatchComponent(MatchNode node, List<MatchEdge> populatedEdges, WSqlTableContext context) : this(node) { Context = context; foreach (var edge in populatedEdges) { TableRef = SpanTableRef(TableRef, edge, node.RefAlias); EdgeMaterilizedDict[edge] = true; StatisticsDict[edge.SinkNode] = Context.GetEdgeStatistics(edge); var edgeList = UnmaterializedNodeMapping.GetOrCreate(edge.SinkNode); edgeList.Add(edge); Nodes.Add(edge.SinkNode); Size *= edge.AverageDegree; EstimateSize *= 1000; } }
public MatchComponent(MatchNode node):this() { Nodes.Add(node); MaterializedNodeSplitCount[node] = 0; StatisticsDict[node] = new ColumnStatistics{Selectivity = 1.0/node.TableRowCount}; Size *= node.EstimatedRows; EstimateSize *= node.EstimatedRows; TableRef = new WNamedTableReference { Alias = new Identifier { Value = node.RefAlias}, TableObjectName = node.TableObjectName }; }
private CandidateJoinUnit GetCandidateUnits2(OneHeightTree tree, MatchComponent component) { Dictionary <string, MatchEdge> revEdgeDict = this.Graph.ReversedEdgeDict; MatchNode root = tree.TreeRoot; List <MatchEdge> inEdges; component.UnmaterializedNodeMapping.TryGetValue(root, out inEdges); List <MatchEdge> outEdges = new List <MatchEdge>(); List <MatchEdge> unpopEdges = new List <MatchEdge>(); foreach (MatchEdge edge in tree.Edges) { if (component.Nodes.ContainsKey(edge.SinkNode.NodeAlias)) { outEdges.Add(edge); } else { unpopEdges.Add(edge); } } Dictionary <string, Tuple <MatchEdge, EdgeDir> > rawEdges = new Dictionary <string, Tuple <MatchEdge, EdgeDir> >(); Dictionary <string, MatchEdge> extInEdges = new Dictionary <string, MatchEdge>(); if (inEdges != null) { rawEdges = inEdges.ToDictionary(edge => edge.EdgeAlias, edge => new Tuple <MatchEdge, EdgeDir>(edge, EdgeDir.In)); extInEdges = inEdges.ToDictionary(edge => edge.EdgeAlias); } foreach (MatchEdge edge in outEdges) { string key = edge.EdgeAlias; rawEdges.Add(key, new Tuple <MatchEdge, EdgeDir>(edge, EdgeDir.Out)); extInEdges.Add(key, revEdgeDict[key]); } if (extInEdges.Any()) { KeyValuePair <string, MatchEdge> firstEdge = extInEdges.FirstOrDefault(e => e.Value.IsReversed == false); if (firstEdge.Value == null) { firstEdge = extInEdges.First(); } Dictionary <string, MatchEdge> preMatInEdges = new Dictionary <string, MatchEdge> { { firstEdge.Key, firstEdge.Value } }; List <Tuple <MatchEdge, EdgeDir> > postMatEdges = rawEdges.Where(entry => !preMatInEdges.ContainsKey(entry.Key)) .Select(entry => entry.Value).ToList(); List <MatchEdge> postMatIncomingEdges = postMatEdges.Where(entry => entry.Item2 == EdgeDir.In).Select(entry => entry.Item1).ToList(); List <MatchEdge> postMatOutgoingEdges = postMatEdges.Where(entry => entry.Item2 == EdgeDir.Out).Select(entry => entry.Item1).ToList(); return(new CandidateJoinUnit { TreeRoot = root, PreMatIncomingEdges = preMatInEdges.Select(entry => entry.Value).ToList(), PreMatOutgoingEdges = new List <MatchEdge>(), PostMatIncomingEdges = postMatIncomingEdges, PostMatOutgoingEdges = postMatOutgoingEdges, UnmaterializedEdges = unpopEdges, }); } else { throw new GraphViewException("This graph pattern is not yet supported."); } }
/// <summary> /// Add an tuple to a new order, and update information /// </summary> /// <param name="tuple"></param> public void AddTuple(Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> > tuple) { if (tuple.Item2 is PredicateLink) { this.ExistingPredicateLinks.Add(tuple.Item2.LinkAlias); } else if (tuple.Item2 is MatchEdge) { this.ExistingNodesAndEdges.Add(tuple.Item2.LinkAlias); this.ReadyEdges.Remove(tuple.Item2.LinkAlias); } this.ExistingNodesAndEdges.Add(tuple.Item1.NodeAlias); // Check ready edges whether to be generated foreach (Tuple <PredicateLink, int> predicateLinkTuple in tuple.Item3) { this.ExistingPredicateLinks.Add(predicateLinkTuple.Item1.LinkAlias); } if (tuple.Item1 is MatchNode) { MatchNode matchNode = tuple.Item1 as MatchNode; foreach (MatchEdge edge in matchNode.Neighbors) { if (this.ExistingNodesAndEdges.Contains(edge.LinkAlias)) { continue; } else if (tuple.Item4.Exists(edgeTuple => edgeTuple.Item1.LinkAlias == edge.LinkAlias)) { this.ExistingNodesAndEdges.Add(edge.LinkAlias); this.ReadyEdges.Remove(edge.LinkAlias); } else { this.ReadyEdges.Add(edge.LinkAlias); } } foreach (MatchEdge edge in matchNode.ReverseNeighbors) { if (this.ExistingNodesAndEdges.Contains(edge.LinkAlias)) { continue; } else if (tuple.Item4.Exists(edgeTuple => edgeTuple.Item1.LinkAlias == edge.LinkAlias)) { this.ExistingNodesAndEdges.Add(edge.LinkAlias); this.ReadyEdges.Remove(edge.LinkAlias); } else { this.ReadyEdges.Add(edge.LinkAlias); } } foreach (MatchEdge edge in matchNode.DanglingEdges) { if (this.ExistingNodesAndEdges.Contains(edge.LinkAlias)) { continue; } else if (tuple.Item4.Exists(edgeTuple => edgeTuple.Item1.LinkAlias == edge.LinkAlias)) { this.ExistingNodesAndEdges.Add(edge.LinkAlias); this.ReadyEdges.Remove(edge.LinkAlias); } else { this.ReadyEdges.Add(edge.LinkAlias); } } } this.Order.Add(tuple); this.UpdateCost(); }
public MatchComponent(MatchNode node):this() { Nodes.Add(node); MaterializedNodeSplitCount[node] = 0; //SinkNodeStatisticsDict[node] = new Statistics (); Cardinality *= node.EstimatedRows; SqlEstimatedSize *= node.EstimatedRows; TableRef = new WNamedTableReference { Alias = new Identifier { Value = node.RefAlias}, TableObjectName = node.NodeTableObjectName }; }
/// <summary> /// Given a node, we need to find it possible traversalLink, forwardLinks and backwardEdges /// </summary> /// <param name="predicateLinksAccessedTableAliases"></param> /// <param name="node"></param> /// <returns></returns> private List <Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> > > GenerateTuples( List <Tuple <PredicateLink, HashSet <string> > > predicateLinksAccessedTableAliases, CompileNode node) { List <Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> > > nextTuples = new List <Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> > >(); // Find local execution orders List <ExecutionOrder> localExecutionOrders = node.GetLocalExecutionOrder(this).Order.First().Item5; // traversalLinks must be existing edges, ready edges or WEdgeVertexBridgeExpression. List <CompileLink> traversalLinks = new List <CompileLink>(); List <MatchEdge> connectedReadyEdges = new List <MatchEdge>(); List <MatchEdge> connectedUnreadyEdges = new List <MatchEdge>(); // The item2 is the corresponding priority. // If the priority is 1, // then the edge should try to retrieve before retrieve a node or execute a TVF, // and predicates should be evaluated after retrieving the edge // If the priority is 2, // then edges should try to retrieve when retrieving a node (not support in execution part now), // and predicates should be evaluated after retrieving these edges and a node or executing a TVF // If the priority is 3, // then edges should try to retrieve after retrieving a node, // and predicates should be evaluated after retrieving these edges List <Tuple <PredicateLink, int> > forwardLinks = new List <Tuple <PredicateLink, int> >(); List <Tuple <MatchEdge, int> > backwardEdges = new List <Tuple <MatchEdge, int> >(); // Find forwardLinks, backwardEdges and predicates after adding the alias of node if (node is MatchNode) { MatchNode matchNode = node as MatchNode; foreach (MatchEdge edge in matchNode.Neighbors) { if (!this.ExistingNodesAndEdges.Contains(edge.LinkAlias)) { if (this.ReadyEdges.Contains(edge.LinkAlias)) { connectedReadyEdges.Add(edge); } else { connectedUnreadyEdges.Add(edge); } } if (this.ExistingNodesAndEdges.Contains(edge.LinkAlias) || this.ReadyEdges.Contains(edge.LinkAlias)) { traversalLinks.Add(edge); } } foreach (MatchEdge edge in matchNode.ReverseNeighbors) { if (!this.ExistingNodesAndEdges.Contains(edge.LinkAlias)) { if (this.ReadyEdges.Contains(edge.LinkAlias)) { connectedReadyEdges.Add(edge); } else { connectedUnreadyEdges.Add(edge); } } if (this.ExistingNodesAndEdges.Contains(edge.LinkAlias) || this.ReadyEdges.Contains(edge.LinkAlias)) { traversalLinks.Add(edge); } } foreach (MatchEdge edge in matchNode.DanglingEdges) { if (!this.ExistingNodesAndEdges.Contains(edge.LinkAlias)) { connectedUnreadyEdges.Add(edge); } } // Add the node's alias temporarily to find WEdgeVertexBridgeExpression HashSet <string> temporaryAliases = new HashSet <string>(this.ExistingNodesAndEdges); temporaryAliases.Add(matchNode.NodeAlias); foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases) { if (!this.ExistingPredicateLinks.Contains(tuple.Item1.LinkAlias) && temporaryAliases.IsSupersetOf(tuple.Item2) && tuple.Item1.BooleanExpression is WEdgeVertexBridgeExpression) { traversalLinks.Add(tuple.Item1); } } // Find all possible sublists of connectedUnreadyEdges // Because we may not reterieve all edges at this step List <List <MatchEdge> > connectedUnreadyEdgesSublists = GetAllSublists(connectedUnreadyEdges); // if traversalLinks is empty, we add a NULL in it. if (!traversalLinks.Any()) { traversalLinks.Add(null); } // backwardEdges = (connectedReadyEdges) U (a sublist of connectedUnreadyEdges) - (traversalLink) // but connnectedREadyEdges' priorities can be 2 or 3, connectedUnreadyEdges must be 2 foreach (CompileLink traversalLink in traversalLinks) { foreach (List <MatchEdge> connectedUnreadyEdgesSublist in connectedUnreadyEdgesSublists) { List <MatchEdge> connectedReadyEdgesSublist = new List <MatchEdge>(connectedReadyEdges); if (traversalLink is MatchEdge) { connectedReadyEdgesSublist.Remove(traversalLink as MatchEdge); } // Find all combinations of connectedReadyEdges // These readyEdges' priorities can be 2 or 3 List <List <Tuple <MatchEdge, int> > > connectedReadyEdgesCombinations = GetAllCombinations(connectedReadyEdgesSublist, new List <int>() { 2, 3 }); // Find all combinations of connectedUnreadyEdges // All unreadyEdges' priorities must be 2 if retrieving them List <List <Tuple <MatchEdge, int> > > connectedUnreadyEdgesCombinations = GetAllCombinations(connectedUnreadyEdgesSublist, new List <int>() { 2 }); // Find all combinations of connectedReadyEdges and connectedUnreadyEdges foreach (List <Tuple <MatchEdge, int> > connectedReadyEdgesCombination in connectedReadyEdgesCombinations) { foreach (List <Tuple <MatchEdge, int> > connectedUnreadyEdgesCombination in connectedUnreadyEdgesCombinations) { backwardEdges = new List <Tuple <MatchEdge, int> >(connectedReadyEdgesCombination); backwardEdges.AddRange(connectedUnreadyEdgesCombination); forwardLinks = this.FindPredicates(matchNode, traversalLink, backwardEdges, predicateLinksAccessedTableAliases); nextTuples.Add( new Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> >(matchNode, traversalLink, forwardLinks, backwardEdges, localExecutionOrders)); } } } } } else if (node is NonFreeTable) { forwardLinks = this.FindPredicates(node, null, backwardEdges, predicateLinksAccessedTableAliases); nextTuples.Add(new Tuple <CompileNode, CompileLink, List <Tuple <PredicateLink, int> >, List <Tuple <MatchEdge, int> >, List <ExecutionOrder> >( node, null, forwardLinks, backwardEdges, localExecutionOrders)); } else { throw new QueryCompilationException("Can't find " + node.ToString() + " in AggregationBlock"); } return(nextTuples); }
public MatchComponent(MatchNode node, List<MatchEdge> populatedEdges,GraphMetaData metaData) : this(node) { foreach (var edge in populatedEdges) { TableRef = SpanTableRef(TableRef, edge, node.RefAlias, metaData); EdgeMaterilizedDict[edge] = true; SinkNodeStatisticsDict[edge.SinkNode] = edge.Statistics; var edgeList = UnmaterializedNodeMapping.GetOrCreate(edge.SinkNode); edgeList.Add(edge); if (!Nodes.Contains(edge.SinkNode)) Nodes.Add(edge.SinkNode); Cardinality *= edge.AverageDegree; SqlEstimatedSize *= 1000; } }
private static WColumnReferenceExpression GetNodeColumnReferenceExprFromAnExistingEdge(MatchNode node, HashSet <string> existingNodeAndEdges) { if (node == null) { return(null); } foreach (MatchEdge edge in node.Neighbors) { if (existingNodeAndEdges.Contains(edge.LinkAlias)) { return(GetNodeColumnReferenceExprFromLink(edge)); } } foreach (MatchEdge edge in node.ReverseNeighbors) { if (existingNodeAndEdges.Contains(edge.LinkAlias)) { return(GetNodeColumnReferenceExprFromLink(edge)); } } foreach (MatchEdge edge in node.DanglingEdges) { if (existingNodeAndEdges.Contains(edge.LinkAlias)) { return(GetNodeColumnReferenceExprFromLink(edge)); } } return(null); }
public bool TryGetNode(string key, out MatchNode node) { foreach (var subGraph in ConnectedSubGraphs) { if (subGraph.Nodes.TryGetValue(key, out node)) { return true; } } node = null; return false; }
public MatchComponent(MatchNode node) : this() { Nodes.Add(node); MaterializedNodeSplitCount[node] = 0; //SinkNodeStatisticsDict[node] = new Statistics (); Cardinality *= node.EstimatedRows; SqlEstimatedSize *= node.EstimatedRows; TableRef = new WNamedTableReference { Alias = new Identifier { Value = node.RefAlias}, TableObjectName = node.NodeTableObjectName }; LastTableAlias = node.RefAlias; LastTable = null; foreach (var edge in node.Neighbors) { var edgeList = UnmaterializedNodeMapping.GetOrCreate(edge.SinkNode); edgeList.Add(edge); } }
public NodeQuery(Dictionary <string, int> GraphDescription, MatchNode node) { NodeNum = GraphDescription[node.NodeAlias]; NodeAlias = node.NodeAlias; NodeSlectClause = node.DocDBQuery.Replace("'", "\""); }