private IEnumerable <ThreadInfo> GetPartitionPaths(ThreadManager TM, Stack <PartitionPass> partitions, Dictionary <int, SortedSet <Node> > goalNodes) { var currentThread = TM.CurrentThread; var currentNode = partitions.Peek().Target; var paths = new List <List <PartitionPass> >(); // Travel to other partitions, and get the paths through them yield return(TM.Await(currentThread, GetNodePartitions(TM, currentNode, "spGetNodePartitions"))); var nodePartitions = TM.GetResult <SortedSet <int> >(currentThread).Except(partitions.Select((PartitionPass pp) => pp.Partition)); foreach (int partition in nodePartitions) { // See if any goal nodes are in this partition if (goalNodes.ContainsKey(partition)) { foreach (var goalNode in goalNodes[partition]) { partitions.Push(new PartitionPass(partition, goalNode, _settings.WeightedDist(currentNode, goalNode))); var path = partitions.Reverse().Skip(1).ToList(); paths.Add(path); partitions.Pop(); } } // Go to all the boundaries of this partition yield return(TM.Await(currentThread, GetPartitionBoundaries(TM, partition))); var targetNodes = TM.GetResult <SortedSet <Node> >(currentThread); if (goalNodes.ContainsKey(partition)) { targetNodes.ExceptWith(goalNodes[partition]); } targetNodes.Remove(currentNode); foreach (var targetNode in targetNodes) { partitions.Push(new PartitionPass(partition, targetNode, _settings.WeightedDist(currentNode, targetNode))); yield return(TM.Await(currentThread, GetPartitionPaths(TM, partitions, goalNodes))); paths.AddRange(TM.GetResult <List <List <PartitionPass> > >(currentThread)); partitions.Pop(); } } yield return(TM.Return(currentThread, paths)); }
public IEnumerable <ThreadInfo> GetDirections(ThreadManager TM, int to, Dictionary <string, string> query) { var currentThread = TM.CurrentThread; _settings = new DirectionsSettings(query); yield return(TM.Await(currentThread, GetShortestPath(TM, to))); _pathFindingDone = 1; yield return(TM.Await(currentThread, GetDirectionMessages(TM))); _messageFindingDone = 1; yield return(TM.Sleep(currentThread, 60000)); _directions.Remove(_id); yield return(TM.Return(currentThread)); }
public IEnumerable <ThreadInfo> HandlePath(ThreadManager TM, IEnumerable <string> path, Dictionary <string, string> query, object state) { var currentThread = TM.CurrentThread; if (path.Any()) { if (Redirects.ContainsKey(path.First())) { yield return(TM.Await(currentThread, Redirects[path.First()].HandlePath(TM, path.Skip(1), query, state))); } else { int intValue; if (Int32.TryParse(path.First(), out intValue)) { yield return(TM.Await(currentThread, HandleIntPath(TM, intValue, state))); if (!(TM.GetResultNoException(currentThread) is JsonResponse)) { yield return(TM.Await(currentThread, IntRedirect.HandlePath(TM, path.Skip(1), query, TM.GetResult(currentThread)))); } } else { double floatValue; if (Double.TryParse(path.First(), out floatValue)) { yield return(TM.Await(currentThread, HandleFloatPath(TM, floatValue, state))); if (!(TM.GetResultNoException(currentThread) is JsonResponse)) { yield return(TM.Await(currentThread, FloatRedirect.HandlePath(TM, path.Skip(1), query, TM.GetResult(currentThread)))); } } else { yield return(TM.Await(currentThread, HandleUnknownPath(TM, path.First(), state))); if (!(TM.GetResultNoException(currentThread) is JsonResponse)) { yield return(TM.Await(currentThread, UnknownRedirect.HandlePath(TM, path.Skip(1), query, TM.GetResult(currentThread)))); } } } } } else { yield return(TM.Await(currentThread, HandleNoPath(TM, query, state))); } yield return(TM.Return(currentThread)); }
private static IEnumerable <ThreadInfo> HandleRequest(ThreadManager TM, HttpListenerContext context) { var currentThread = TM.CurrentThread; JsonResponse result = null; var path = Uri.UnescapeDataString(context.Request.Url.LocalPath).Split('/').SkipWhile(String.IsNullOrEmpty).TakeWhile(s => !String.IsNullOrEmpty(s)); Dictionary <string, string> query = new Dictionary <string, string>(); if (!String.IsNullOrEmpty(context.Request.Url.Query)) { var querySplit = Uri.UnescapeDataString(context.Request.Url.Query).Split('?', '&', ';').Skip(1); foreach (string field in querySplit) { int equalsPos = field.IndexOf('='); if (equalsPos == -1 || equalsPos == 0 || equalsPos == field.Length - 1) { result = new JsonResponse(HttpStatusCode.BadRequest); break; } query.Add(field.Substring(0, equalsPos), field.Substring(equalsPos + 1, field.Length - equalsPos - 1)); } } if (result == null) { yield return(TM.Await(currentThread, _handler.HandlePath(TM, path, query, new object()))); try { result = TM.GetResult <JsonResponse>(currentThread); } catch (Exception) { result = new JsonResponse(HttpStatusCode.InternalServerError); } } var encoding = new ASCIIEncoding(); byte[] b; if (result.Json != null) { b = encoding.GetBytes(result.Json.Serialize()); } else { b = encoding.GetBytes(result.Message); } context.Response.OutputStream.Write(b, 0, b.Length); context.Response.StatusCode = (int)result.StatusCode; context.Response.Close(); yield return(TM.Return(currentThread, null)); }
protected virtual IEnumerable <ThreadInfo> HandleIntPath(ThreadManager TM, int value, object state) { var currentThread = TM.CurrentThread; if (IntRedirect != null) { yield return(TM.Return(currentThread, value)); } else { yield return(TM.Await(currentThread, HandleFloatPath(TM, value, state))); yield return(TM.Return(currentThread)); } }
private IEnumerable <ThreadInfo> GetShortestPath(ThreadManager TM, int to) { var currentThread = TM.CurrentThread; // See if the start node is already in the goal location yield return(TM.MakeDbCall(currentThread, Program.ConnectionString, "spGetLocationNodes", new SqlParameter("@location", to))); using (var table = TM.GetResult <DataTable>(currentThread)) { if (table.Rows.Count == 0) { // Error - no nodes in goal location yield return(TM.Return(currentThread)); } foreach (DataRow row in table.Rows) { if (new Node(row).Id == _start.Id) { // Already at goal yield return(TM.Return(currentThread)); } } } // Get the nodes on the boundary of the goal location var goalNodes = new Dictionary <int, SortedSet <Node> >(); yield return(TM.MakeDbCall(currentThread, Program.ConnectionString, "spGetLocationBoundaryNodes", new SqlParameter("@location", to))); using (var table = TM.GetResult <DataTable>(currentThread)) { if (table.Rows.Count == 0) { // Error - no nodes on goal location's boundary yield return(TM.Return(currentThread)); } foreach (DataRow row in table.Rows) { var node = new Node(row); if (!goalNodes.ContainsKey(node.Partition.Value)) { goalNodes[node.Partition.Value] = new SortedSet <Node>(new NodeComparer()); } goalNodes[node.Partition.Value].Add(node); } } // Get the possible partition paths Stack <PartitionPass> partitions = new Stack <PartitionPass>(); partitions.Push(new PartitionPass(-1, _start, 0)); yield return(TM.Await(currentThread, GetPartitionPaths(TM, partitions, goalNodes))); var passes = TM.GetResult <List <List <PartitionPass> > >(currentThread); SortedSet <TargetPath> queue = new SortedSet <TargetPath>(new TargetPathComparer()); Dictionary <int, ShortestPath> shortestPaths = new Dictionary <int, ShortestPath>(); shortestPaths[_start.Id] = new ShortestPath(); foreach (var pass in passes) { queue.Add(new TargetPath(_start, 0, pass, queue, _settings)); } while (true) { var currentPath = queue.First(); _pathFindingDone = Math.Max(_pathFindingDone, currentPath.DistSoFar * currentPath.DistSoFar / (currentPath.BestDist * currentPath.BestDist)); if (goalNodes.Any(kvp => kvp.Value.Contains(currentPath.CurrentNode))) { var currentNode = currentPath.CurrentNode; var prevNode = shortestPaths[currentNode.Id].PrevNode; _paths.Add(new DirectionPath(currentNode.Lat, currentNode.Lon, null, true, null, currentNode.Altitude, currentNode.Location, currentNode.Outside, shortestPaths[currentNode.Id].Id, shortestPaths[currentNode.Id].Forward)); while (currentNode.Id != _start.Id) { _paths.Insert(0, new DirectionPath(prevNode.Lat, prevNode.Lon, null, false, null, prevNode.Altitude, prevNode.Location, prevNode.Outside, shortestPaths[currentNode.Id].Id, shortestPaths[currentNode.Id].Forward)); currentNode = prevNode; prevNode = shortestPaths[currentNode.Id].PrevNode; } _paths.First().Flag = true; yield return(TM.Return(currentThread)); } yield return(TM.MakeDbCall(currentThread, Program.ConnectionString, "spGetPathsFromNode", new SqlParameter("@node", currentPath.CurrentNode.Id), new SqlParameter("@part", currentPath.PartitionsLeft.First().Partition))); using (var table = TM.GetResult <DataTable>(currentThread)) { foreach (DataRow row in table.Rows) { var path = new PathToNode(row, currentPath.CurrentNode.Id, currentPath.PartitionsLeft.First().Partition); double pathDist = _settings.WeightedDist(currentPath.CurrentNode, path.Node); if (shortestPaths.ContainsKey(path.Node.Id)) { if (shortestPaths[path.Node.Id].TotalDist > currentPath.DistSoFar + pathDist) { shortestPaths[path.Node.Id].SetPrevNode(currentPath.CurrentNode, pathDist, path.Path.Id, path.Forward, shortestPaths); } else if (shortestPaths[path.Node.Id].TotalDist < currentPath.DistSoFar + pathDist) { continue; } // TODO } else { shortestPaths[path.Node.Id] = new ShortestPath(currentPath.CurrentNode, pathDist, path.Path.Id, path.Forward, shortestPaths); // TODO } if (path.Node.Id == currentPath.PartitionsLeft.First().Target.Id) { queue.Add(new TargetPath(path.Node, shortestPaths[path.Node.Id].TotalDist, currentPath.PartitionsLeft.Skip(1).ToList(), queue, _settings)); } else { queue.Add(new TargetPath(path.Node, shortestPaths[path.Node.Id].TotalDist, currentPath.PartitionsLeft, queue, _settings)); } } } queue.Remove(currentPath); } }