public async Task <byte[]> LoadBytesFromPath(RelativePath path) { var fullPath = ExtractedModlistFolder !.Dir.Combine(path); if (!fullPath.IsFile) { throw new Exception($"Cannot load inlined data {path} file does not exist"); } return(await fullPath.ReadAllBytesAsync()); }
public static bool RunTest(string toolchainName, Compiler compile, Exe runner, File source) { var destPath = tests_results.Combine(source); var sourcePath = tests.Combine(source); var expected = sourcePath.DropExtension().Combine(Ext(".o")); Console.Write($"\x1b[KRunning test {source} ({toolchainName}) "); destPath.DirName().Create(); UserErrorException exception = null; try { CompileToFile(compile, sourcePath, destPath); } catch (UserErrorException e) { exception = e; } if (exception != null) { Console.WriteLine(""); Console.WriteLine("\x1b[1;31mFail\x1b[m"); Console.WriteLine($"\x1b[1;33m{exception.Message}\x1b[m\n"); return(false); } else { var actualStr = runner.Run(destPath); var expectedStr = expected.Read(); if (actualStr != expectedStr) { Console.WriteLine("\x1b[1;31mFail\x1b[m"); Console.WriteLine($"\x1b[1;33m{source}: expected {expectedStr} but got {actualStr}.\x1b[m\n"); return(false); } else { Console.Write("\x1b[1;32mOK\x1b[m\n"); // \r at the end for quiet return(true); } } }
/// <summary> /// Executes the actual algorithm. /// </summary> protected override void DoRun() { float distance; ushort edgeProfile; var enumerator1 = _source.GetEdgeEnumerator(); var enumerator2 = _source.GetEdgeEnumerator(); for (uint v = 0; v < _source.VertexCount; v++) { enumerator1.MoveTo(v); while (enumerator1.MoveNext()) { EdgeDataSerializer.Deserialize(enumerator1.Data0, out distance, out edgeProfile); var accessible1 = false; var weight1 = _weightHandler.CalculateWeightAndDir(edgeProfile, distance, out accessible1); if (enumerator1.DataInverted) { var dir = weight1.Direction; dir.Reverse(); weight1.Direction = dir; } if (!accessible1) { // not accessible. continue; } var direction1 = weight1.Direction; var edge1 = enumerator1.DirectedEdgeId(); // look at the neighbours of this edge. enumerator2.MoveTo(enumerator1.To); _restrictions.Update(enumerator1.To); while (enumerator2.MoveNext()) { var turn = new Turn(new OriginalEdge(v, enumerator1.To), Constants.NO_VERTEX); EdgeDataSerializer.Deserialize(enumerator2.Data0, out distance, out edgeProfile); var accessible2 = false; var weight2 = _weightHandler.CalculateWeightAndDir(edgeProfile, distance, out accessible2); if (enumerator2.DataInverted) { var dir = weight2.Direction; dir.Reverse(); weight2.Direction = dir; } if (!accessible2) { // not accessible. continue; } var direction2 = weight2.Direction; turn.Vertex3 = enumerator2.To; if (turn.IsUTurn) { // is a u-turn, leave this out! continue; } var direction = Dir.Combine(direction1, direction2); if (direction.F && turn.IsRestrictedBy(_restrictions)) { // turn is restricted. direction.F = false; } if (!direction.F) { // there is no possible combination for these two edges. continue; } // ok, we need to add this edge, it's a non-restricted turn, not a u-turn and edges are in correct direction. var edge2 = enumerator2.DirectedEdgeId(); _weightHandler.AddOrUpdateEdge(_target, edge1.Raw, edge2.Raw, Constants.NO_VERTEX, true, weight1.Weight); //direction.Reverse(); _weightHandler.AddOrUpdateEdge(_target, edge2.Raw, edge1.Raw, Constants.NO_VERTEX, false, weight1.Weight); } } } }
/// <summary> /// Calculates witness paths. /// </summary> public virtual void Calculate(DirectedGraph graph, WeightHandler <T> weightHandler, uint vertex, uint source, Dictionary <uint, Shortcut <T> > targets, int maxSettles, int hopLimit) { pathTree.Clear(); pointerHeap.Clear(); var forwardSettled = new HashSet <uint>(); var backwardSettled = new HashSet <uint>(); var forwardTargets = new HashSet <uint>(); var backwardTargets = new HashSet <uint>(); var maxWeight = 0f; foreach (var targetPair in targets) { var target = targetPair.Key; var shortcut = targetPair.Value; var e = new OriginalEdge(source, target); var shortcutForward = weightHandler.GetMetric(shortcut.Forward); if (shortcutForward > 0 && shortcutForward < float.MaxValue) { forwardTargets.Add(e.Vertex2); if (shortcutForward > maxWeight) { maxWeight = shortcutForward; } } var shortcutBackward = weightHandler.GetMetric(shortcut.Backward); if (shortcutBackward > 0 && shortcutBackward < float.MaxValue) { backwardTargets.Add(e.Vertex2); if (shortcutBackward > maxWeight) { maxWeight = shortcutBackward; } } } // queue the source. pathTree.Clear(); pointerHeap.Clear(); var p = pathTree.AddSettledVertex(source, new WeightAndDir <float>() { Direction = new Dir(true, true), Weight = 0 }, 0); pointerHeap.Push(p, 0); // dequeue vertices until stopping conditions are reached. var cVertex = Constants.NO_VERTEX; WeightAndDir <float> cWeight; var cHops = uint.MaxValue; var enumerator = graph.GetEdgeEnumerator(); while (pointerHeap.Count > 0) { var cPointer = pointerHeap.Pop(); pathTree.GetSettledVertex(cPointer, out cVertex, out cWeight, out cHops); if (cVertex == vertex) { continue; } if (cWeight.Weight >= maxWeight) { break; } if (forwardSettled.Contains(cVertex) || forwardTargets.Count == 0 || forwardSettled.Count > maxSettles) { cWeight.Direction = new Dir(false, cWeight.Direction.B); } if (backwardSettled.Contains(cVertex) || backwardTargets.Count == 0 || backwardSettled.Count > maxSettles) { cWeight.Direction = new Dir(cWeight.Direction.F, false); } if (cWeight.Direction.F) { forwardSettled.Add(cVertex); if (forwardTargets.Contains(cVertex)) { // target reached, evaluate it as a shortcut. Shortcut <T> shortcut; if (targets.TryGetValue(cVertex, out shortcut)) { var shortcutForward = weightHandler.GetMetric(shortcut.Forward); if (shortcutForward > cWeight.Weight) { // a witness path was found, don't add a shortcut. shortcut.Forward = weightHandler.Zero; targets[cVertex] = shortcut; } } forwardTargets.Remove(cVertex); if (forwardTargets.Count == 0) { if (backwardTargets.Count == 0) { break; } cWeight.Direction = new Dir(false, cWeight.Direction.B); if (!cWeight.Direction.F && !cWeight.Direction.B) { continue; } } } } if (cWeight.Direction.B) { backwardSettled.Add(cVertex); if (backwardTargets.Contains(cVertex)) { // target reached, evaluate it as a shortcut. Shortcut <T> shortcut; if (targets.TryGetValue(cVertex, out shortcut)) { var shortcutBackward = weightHandler.GetMetric(shortcut.Backward); if (shortcutBackward > cWeight.Weight) { // a witness path was found, don't add a shortcut. shortcut.Backward = weightHandler.Zero; targets[cVertex] = shortcut; } } backwardTargets.Remove(cVertex); if (backwardTargets.Count == 0) { if (forwardTargets.Count == 0) { break; } cWeight.Direction = new Dir(cWeight.Direction.F, false); if (!cWeight.Direction.F && !cWeight.Direction.B) { continue; } } } } if (cHops + 1 >= hopLimit) { continue; } if (forwardSettled.Count > maxSettles && backwardSettled.Count > maxSettles) { continue; } enumerator.MoveTo(cVertex); while (enumerator.MoveNext()) { var nVertex = enumerator.Neighbour; var nWeight = ContractedEdgeDataSerializer.Deserialize(enumerator.Data0); nWeight = new WeightAndDir <float>() { Direction = Dir.Combine(cWeight.Direction, nWeight.Direction), Weight = cWeight.Weight + nWeight.Weight }; if (nWeight.Direction.F && forwardSettled.Contains(nVertex)) { nWeight.Direction = new Dir(false, nWeight.Direction.B); } if (nWeight.Direction.B && backwardSettled.Contains(nVertex)) { nWeight.Direction = new Dir(nWeight.Direction.F, false); } if (!nWeight.Direction.F && !nWeight.Direction.B) { continue; } var nPoiner = pathTree.AddSettledVertex(nVertex, nWeight, cHops + 1); pointerHeap.Push(nPoiner, nWeight.Weight); } } }