private GraphPath(GraphPath parent, Identity node, EdgeInfo fromEdge) { DomainModel = parent.DomainModel; _parent = parent; EndElement = node; LastTraversedRelationship = fromEdge; }
///------------------------------------------------------------------------------------------------- /// <summary> /// Returns what to do with this path in a traversal query. /// </summary> /// <param name="path"> /// Full pathname of the file. /// </param> /// <returns> /// A GraphTraversalEvaluatorResult. /// </returns> ///------------------------------------------------------------------------------------------------- public GraphTraversalEvaluatorResult Visit(GraphPath path) { return(GraphTraversalEvaluatorResult.IncludeAndContinue); }
///------------------------------------------------------------------------------------------------- /// <summary> /// Called when a path is visited. /// </summary> /// <param name="path"> /// Full pathname of the file. /// </param> ///------------------------------------------------------------------------------------------------- public void MarkVisited(GraphPath path) { DebugContract.Requires(path); _visited.Add(path); }
///------------------------------------------------------------------------------------------------- /// <summary> /// Returns if a path has been visited. /// </summary> /// <param name="path"> /// Full pathname of the file. /// </param> /// <returns> /// True is the path has been visited. /// </returns> ///------------------------------------------------------------------------------------------------- public bool IsVisited(GraphPath path) { DebugContract.Requires(path); return(_visited.Contains(path)); }
///------------------------------------------------------------------------------------------------- /// <summary> /// Enumerates the items in this collection that meet given criteria. /// </summary> /// <param name="node"> /// The node. /// </param> /// <returns> /// An enumerator that allows foreach to be used to process the matched items. /// </returns> ///------------------------------------------------------------------------------------------------- public virtual IEnumerable <GraphPath> Traverse(NodeInfo node) { DebugContract.Requires(node); // Création du container de stockage des noeuds (ou plutot des chemins jusqu'à ce noeud) restant à traverser // Le type est tributaire de l'algorithme de traversé (Queue pour BreadthFirst et Stack pour DepthFirst) // Ce container est mis à jour à chaque noeud. var paths = CreatePathContainer(); // Lecture du noeud de départ if (node == null) { yield break; } // Constitution du Path courant var path = new GraphPath(_query.DomainModel, node.Id); // Initialisation du container avec le 1er noeud paths.Insert(new[] { path }); // Tant qu'il y a des noeuds à parcourir while (!paths.IsEmpty) { // On prend le prochain noeud à parcourir (dépend de l'algo de traversé) path = paths.Retrieve(); // On indique que ce noeud a été visité _query.UnicityPolicy.MarkVisited(path); // Filtrage du chemin courant pour savoir si on continue var result = _query.Evaluator.Visit(path); // Le chemin courant est à prendre en compte if ((GraphTraversalEvaluatorResult.Include & result) == GraphTraversalEvaluatorResult.Include) { // _trace.WriteTrace(TraceCategory.Traverser, "Include : {0}", path); yield return(path); } // Arrêt forcé if ((result & GraphTraversalEvaluatorResult.Exit) == GraphTraversalEvaluatorResult.Exit) { break; } if ((result & GraphTraversalEvaluatorResult.Continue) == GraphTraversalEvaluatorResult.Continue) { var childPaths = new List <GraphPath>(31); // Parcours de toutes les relations du noeud courant pour tester si // on les prend en compte foreach (var rel in _query.IncidencesIterator.From(path.EndElement)) { // _trace.WriteTrace(TraceCategory.Traverser, "Visit : {1} for {0}", path, rel.Id); if (String.Compare(rel.EndId.DomainModelName, _query.DomainModel.Name, StringComparison.OrdinalIgnoreCase) == 0) { var childNode = rel.EndId; var p = path.Create(childNode, rel); // Si ce chemin n'a pas dèjà été traité, on l'ajoute dans la liste des chemins à traiter if (!_query.UnicityPolicy.IsVisited(p)) { // _trace.WriteTrace(TraceCategory.Traverser, "Push : {0}", p); childPaths.Add(p); } } } paths.Insert(childPaths); } } }