< Summary

Class:Itinero.Routing.Flavours.Dijkstra.Bidirectional.DijkstraAlgorithm
Assembly:Itinero
File(s):/home/runner/work/routing2/routing2/src/Itinero/Routing/Flavours/Dijkstra/Bidirectional/DijkstraAlgorithm.cs
Covered lines:44
Uncovered lines:11
Coverable lines:55
Total lines:110
Line coverage:80% (44 of 55)
Covered branches:19
Total branches:28
Branch coverage:67.8% (19 of 28)
Tag:232_15462506344

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
get_RoutingNetwork()100%1100%
TryGetVisit(...)100%1100%
Clear()100%10%
GetVisit(...)100%1100%
Push(...)50%2100%
Pop()50%450%
Step(...)72.72%22100%

File(s)

/home/runner/work/routing2/routing2/src/Itinero/Routing/Flavours/Dijkstra/Bidirectional/DijkstraAlgorithm.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using Itinero.Network;
 4using Itinero.Network.Enumerators.Edges;
 5using Itinero.Routing.DataStructures;
 6
 7namespace Itinero.Routing.Flavours.Dijkstra.Bidirectional;
 8
 9internal abstract class DijkstraAlgorithm
 10{
 1811    private readonly PathTree _tree = new();
 1812    private readonly Dictionary<VertexId, (uint p, double cost)> _settled = [];
 1813    private readonly BinaryHeap<uint> _heap = new();
 14    protected readonly RoutingNetworkEdgeEnumerator _enumerator;
 15    protected readonly RoutingNetwork _network;
 16
 1817    protected DijkstraAlgorithm(RoutingNetwork network)
 1818    {
 1819        _network = network;
 20
 1821        _enumerator = network.GetEdgeEnumerator();
 1822    }
 23
 2224    internal RoutingNetwork RoutingNetwork => _network;
 25
 26    protected abstract bool OnQueued(uint visit, EdgeId edge, (double cost, double turnCost) edgeCost, VertexId vertex, 
 27
 28    protected abstract bool OnSettled(uint visit, VertexId vertex, double cost);
 29
 30    protected abstract (double cost, double turnCost) GetCost(RoutingNetworkEdgeEnumerator edgeEnumerator,
 31        IEnumerable<(EdgeId edge, byte? turn)> previousEdges);
 32
 33    internal bool TryGetVisit(VertexId vertex, out (uint p, double cost) visit)
 4034    {
 4035        return _settled.TryGetValue(vertex, out visit);
 4036    }
 37
 38    internal void Clear()
 039    {
 040        _heap.Clear();
 041        _tree.Clear();
 042        _settled.Clear();
 043    }
 44
 45    internal (VertexId vertex, EdgeId edge, bool forward, byte? head, uint previousPointer) GetVisit(uint pointer)
 446    {
 447        return _tree.GetVisit(pointer);
 448    }
 49
 50    internal uint Push(EdgeId edgeId, bool forward, double cost)
 3651    {
 3652        if (!_enumerator.MoveTo(edgeId, forward)) throw new Exception($"Edge not found!");
 53
 3654        var v = _tree.AddVisit(_enumerator, uint.MaxValue);
 3655        _heap.Push(v, cost);
 3656        return v;
 3657    }
 58
 59    internal (uint pointer, (VertexId vertex, EdgeId edge, bool forward, byte? head, uint previousPointer) visit, double
 4060    {
 4061        var currentPointer = _heap.Pop(out var currentCost);
 4062        var currentVisit = _tree.GetVisit(currentPointer);
 4063        while (!_settled.TryAdd(currentVisit.vertex, (currentPointer, currentCost)))
 064        {
 065            currentPointer = uint.MaxValue;
 066            if (_heap.Count == 0) break;
 67
 068            currentPointer = _heap.Pop(out currentCost);
 069            currentVisit = _tree.GetVisit(currentPointer);
 070        }
 71
 4072        return (currentPointer, currentVisit, currentCost);
 4073    }
 74
 75    internal bool Step(uint pointer, (VertexId vertex, EdgeId edge, bool forward, byte? head, uint previousPointer) visi
 4076    {
 77        // log settled and see if we need to continue.
 4078        if (!this.OnSettled(pointer, visit.vertex, cost)) return false;
 79
 80        // check neighbours.
 4081        if (!_enumerator.MoveTo(visit.vertex)) return true;
 8482        while (_enumerator.MoveNext())
 4483        {
 84            // filter out if U-turns or visits on the same edge.
 4485            var neighbourEdge = _enumerator.EdgeId;
 8486            if (neighbourEdge == visit.edge) continue;
 87
 88            // gets the cost of the current edge.
 489            var (neighbourCost, turnCost) = this.GetCost(_enumerator, _tree.GetPreviousEdges(pointer));
 90
 91            // ignore if cost is 0 or infinite.
 492            if (neighbourCost is >= double.MaxValue or <= 0) continue;
 493            if (turnCost is >= double.MaxValue or < 0) continue;
 94
 95            // check if the vertex has to be queued.
 496            var totalCost = neighbourCost + cost + turnCost;
 97
 98            // add visit if not added yet.
 499            var neighbourPointer = _tree.AddVisit(_enumerator, pointer);
 100
 101            // call the on queued method and allow checking for stopping conditions.
 4102            if (!this.OnQueued(neighbourPointer, _enumerator.EdgeId, (neighbourCost, turnCost), _enumerator.Head, totalC
 103
 104            // add visit to heap.
 4105            _heap.Push(neighbourPointer, totalCost);
 4106        }
 107
 40108        return true;
 40109    }
 110}