GetWanderingApproach(NodeSearchContext <T> context, IGraphNode <T> node) { return(node.Peers.OrderByDescending(Options)); }
public IEnumerable <IGraphNode <T> > Search(GraphNodeVisitationControl <T> visitationControl, NodeSearch <T> predicate) { var explorer = visitationControl ?? new GraphNodeVisitationControl <T>(); var previousPredicate = predicate; predicate = (ctx, wanderPoint) => { var pos = ctx.Cursor; var ret = previousPredicate(ctx, wanderPoint); explorer.MarkVisit(pos, explorer.CreateVisitationMark(pos)); return(ret); }; var context = new NodeSearchContext <T>(this, explorer, predicate); try { while (context.Cursor != null) { if (context.RunTime > explorer.Timeout) { yield break; } if (context.CurrentDepth > explorer.MaxVisitDepth) { yield break; } // by default wandering around the center point context.AllowWanderingThisCycle = explorer.AllowWandering; // check the current node before moving outward if (predicate(context, context.Cursor)) { yield return(context.Cursor); } if (context.Closed) { yield break; } // the predicate can opt out of wandering if (!context.AllowWanderingThisCycle) { continue; } if (context.CurrentDepth == 0) { break; } var pos = context.Cursor; foreach (var n in explorer.GetWanderingApproach(context, pos)) { if (context.SearchBehavior(context, n)) { yield return(context.Cursor); } if (context.Closed) { yield break; } if (!context.AllowWanderingThisCycle) { break; } if (context.CurrentDepth == 0) { break; } } } } finally { context.Dispose(); } }