< Summary

Class:Itinero.Network.Search.Islands.RoutingNetworkIslandManager
Assembly:Itinero
File(s):/home/runner/work/routing2/routing2/src/Itinero/Network/Search/Islands/RoutingNetworkIslandManager.cs
Covered lines:72
Uncovered lines:49
Coverable lines:121
Total lines:208
Line coverage:59.5% (72 of 121)
Covered branches:11
Total branches:18
Branch coverage:61.1% (11 of 18)
Tag:251_23667616543

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
.ctor(...)100%1100%
IsEdgeOnIsland(...)100%1100%
IsEdgeOnIsland(...)75%887.5%
GetOrCreateDirectedGraph(...)100%2100%
get_MaxIslandSize()100%1100%
TryGetIslandsFor(...)100%10%
GetIslandsFor(...)100%2100%
BuildForTileAsync()0%40%
Clone()50%276.92%

File(s)

/home/runner/work/routing2/routing2/src/Itinero/Network/Search/Islands/RoutingNetworkIslandManager.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Diagnostics.CodeAnalysis;
 4using System.Threading;
 5using System.Threading.Tasks;
 6using Itinero.Profiles;
 7
 8namespace Itinero.Network.Search.Islands;
 9
 10internal class RoutingNetworkIslandManager
 11{
 40812    private readonly Dictionary<(string profile, uint tile), Task> _tilesInProgress = new();
 40813    private readonly ReaderWriterLockSlim _tilesInProgressLock = new();
 14    private readonly Dictionary<string, Islands> _islands;
 40815    private readonly Dictionary<string, IslandDirectedGraph> _directedGraphs = new();
 40816    private readonly ReaderWriterLockSlim _islandsLock = new();
 17
 23618    internal RoutingNetworkIslandManager(int maxIslandSize)
 23619    {
 23620        this.MaxIslandSize = maxIslandSize;
 23621        _islands = new();
 23622    }
 23
 17224    private RoutingNetworkIslandManager(int maxIslandSize, Dictionary<string, Islands> islands)
 17225    {
 17226        this.MaxIslandSize = maxIslandSize;
 17227        _islands = islands;
 17228    }
 29
 30    /// <summary>
 31    /// Checks if an edge is on an island using the directed graph.
 32    /// Returns true if island, false if not island, null if inconclusive.
 33    /// </summary>
 34    internal bool? IsEdgeOnIsland(Profile profile, EdgeId edgeId) =>
 1635        this.IsEdgeOnIsland(profile.Name, edgeId);
 36
 37    internal bool? IsEdgeOnIsland(string profileName, EdgeId edgeId)
 1638    {
 39        try
 1640        {
 1641            _islandsLock.EnterReadLock();
 42
 1643            if (!_directedGraphs.TryGetValue(profileName, out var dg))
 244                return null;
 45
 1446            if (!_islands.TryGetValue(profileName, out var profileIslands))
 047                return null;
 1448            if (profileIslands.IsEdgeOnIsland(edgeId))
 049                return true;
 50
 1451            if (dg.IsNotIsland(edgeId))
 1252                return false;
 53
 254            return null;
 55        }
 56        finally
 1657        {
 1658            _islandsLock.ExitReadLock();
 1659        }
 1660    }
 61
 62    internal IslandDirectedGraph GetOrCreateDirectedGraph(Profile profile)
 3063    {
 64        try
 3065        {
 3066            _islandsLock.EnterUpgradeableReadLock();
 67
 5168            if (_directedGraphs.TryGetValue(profile.Name, out var dg)) return dg;
 69
 70            try
 971            {
 972                _islandsLock.EnterWriteLock();
 73
 974                dg = new IslandDirectedGraph();
 975                _directedGraphs[profile.Name] = dg;
 976                return dg;
 77            }
 78            finally
 979            {
 980                _islandsLock.ExitWriteLock();
 981            }
 82        }
 83        finally
 3084        {
 3085            _islandsLock.ExitUpgradeableReadLock();
 3086        }
 3087    }
 88
 34189    internal int MaxIslandSize { get; }
 90
 91    internal bool TryGetIslandsFor(string profileName, out Islands islands)
 092    {
 93        try
 094        {
 095            _islandsLock.EnterReadLock();
 96
 097            return _islands.TryGetValue(profileName, out islands);
 98        }
 99        finally
 0100        {
 0101            _islandsLock.ExitReadLock();
 0102        }
 0103    }
 104
 105    internal Islands GetIslandsFor(Profile profile)
 35106    {
 107        try
 35108        {
 35109            _islandsLock.EnterUpgradeableReadLock();
 110
 61111            if (_islands.TryGetValue(profile.Name, out var islands)) return islands;
 112
 113            try
 9114            {
 9115                _islandsLock.EnterWriteLock();
 116
 9117                islands = new Islands();
 9118                _islands[profile.Name] = islands;
 9119                return islands;
 120            }
 121            finally
 9122            {
 9123                _islandsLock.ExitWriteLock();
 9124            }
 125        }
 126        finally
 35127        {
 35128            _islandsLock.ExitUpgradeableReadLock();
 35129        }
 35130    }
 131
 132    internal async Task BuildForTileAsync(RoutingNetwork network, Profile profile, uint tileId,
 133        CancellationToken cancellationToken)
 0134    {
 135        // queue task, if not done yet.
 136        Task task;
 137        try
 0138        {
 0139            _tilesInProgressLock.EnterUpgradeableReadLock();
 140
 0141            if (!_tilesInProgress.TryGetValue((profile.Name, tileId), out task))
 0142            {
 143                try
 0144                {
 0145                    _tilesInProgressLock.EnterWriteLock();
 146
 0147                    task = IslandBuilder.BuildForTileAsync(network, profile, tileId, cancellationToken);
 0148                    _tilesInProgress[(profile.Name, tileId)] = task;
 0149                }
 150                finally
 0151                {
 0152                    _tilesInProgressLock.ExitWriteLock();
 0153                }
 0154            }
 0155        }
 156        finally
 0157        {
 0158            _tilesInProgressLock.ExitUpgradeableReadLock();
 0159        }
 160
 161        // await the task.
 0162        await task;
 163
 164        // remove from the queue.
 165        try
 0166        {
 0167            _tilesInProgressLock.EnterUpgradeableReadLock();
 168
 0169            if (_tilesInProgress.ContainsKey((profile.Name, tileId)))
 0170            {
 171                try
 0172                {
 0173                    _tilesInProgressLock.EnterWriteLock();
 174
 0175                    _tilesInProgress.Remove((profile.Name, tileId));
 0176                }
 177                finally
 0178                {
 0179                    _tilesInProgressLock.ExitWriteLock();
 0180                }
 0181            }
 0182        }
 183        finally
 0184        {
 0185            _tilesInProgressLock.ExitUpgradeableReadLock();
 0186        }
 0187    }
 188
 189    internal RoutingNetworkIslandManager Clone()
 172190    {
 191        try
 172192        {
 172193            _islandsLock.EnterReadLock();
 194
 172195            var islands = new Dictionary<string, Islands>();
 516196            foreach (var (profileName, profileIslands) in _islands)
 0197            {
 0198                islands[profileName] = profileIslands.Clone();
 0199            }
 200
 172201            return new RoutingNetworkIslandManager(this.MaxIslandSize, islands);
 202        }
 203        finally
 172204        {
 172205            _islandsLock.ExitReadLock();
 172206        }
 172207    }
 208}