GetWanderingApproach(NodeSearchContext <T> context, IGraphNode <T> node)
 {
     return(node.Peers.OrderByDescending(Options));
 }
示例#2
0
        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();
            }
        }