< Summary

Class:Itinero.Network.Search.Islands.Islands
Assembly:Itinero
File(s):/home/runner/work/routing2/routing2/src/Itinero/Network/Search/Islands/Islands.cs
Covered lines:90
Uncovered lines:25
Coverable lines:115
Total lines:256
Line coverage:78.2% (90 of 115)
Covered branches:4
Total branches:10
Branch coverage:40% (4 of 10)
Tag:263_26948838820

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor()100%1100%
.ctor(...)100%10%
SetTileDone(...)100%1100%
GetTileDone(...)100%1100%
IsEdgeOnIsland(...)100%1100%
SetEdgeOnIsland(...)100%1100%
IsEdgeOnIsland(...)100%2100%
SetEdgeOnIsland(...)100%2100%
ClearNonLocalIslandEdges()100%1100%
IsEdgeLocal(...)100%1100%
SetEdgeLocal(...)100%1100%
Clone()0%60%

File(s)

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

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Threading;
 3
 4namespace Itinero.Network.Search.Islands;
 5
 6internal class Islands
 7{
 8    private readonly HashSet<uint> _tiles; // holds the tiles that have been processed.
 439    private readonly ReaderWriterLockSlim _tilesLock = new();
 10    private readonly HashSet<EdgeId> _islandEdges;
 4311    private readonly ReaderWriterLockSlim _islandEdgesLock = new();
 12    private readonly HashSet<EdgeId> _localEdges;
 4313    private readonly ReaderWriterLockSlim _localEdgesLock = new();
 14
 15    // Transient state used during the NonLocal classification pass: each
 16    // edge the classifier identifies as Island in the N-only subgraph is
 17    // recorded here. Once both passes complete and the coordinator has
 18    // computed _localEdges from the gap (NonLocal-Island ∩ NotIsland-Full
 19    // ∩ non-L), this set can be cleared. Not part of the persistent
 20    // storage contract.
 21    private readonly HashSet<EdgeId> _nonLocalIslandEdges;
 4322    private readonly ReaderWriterLockSlim _nonLocalIslandEdgesLock = new();
 23
 4324    internal Islands()
 4325    {
 4326        _tiles = [];
 4327        _islandEdges = [];
 4328        _localEdges = [];
 4329        _nonLocalIslandEdges = [];
 4330    }
 31
 032    private Islands(HashSet<uint> tiles, HashSet<EdgeId> islandEdges, HashSet<EdgeId> localEdges)
 033    {
 034        _tiles = tiles;
 035        _islandEdges = islandEdges;
 036        _localEdges = localEdges;
 037        _nonLocalIslandEdges = [];
 038    }
 39
 40    /// <summary>
 41    /// Sets the tile as done.
 42    /// </summary>
 43    /// <param name="tileId">Sets the tile as done.</param>
 44    /// <returns>True if the tile is done.</returns>
 45    public bool SetTileDone(uint tileId)
 1446    {
 47        try
 1448        {
 1449            _tilesLock.EnterWriteLock();
 50
 1451            return _tiles.Add(tileId);
 52        }
 53        finally
 1454        {
 1455            _tilesLock.ExitWriteLock();
 1456        }
 1457    }
 58
 59    /// <summary>
 60    /// Returns true if the given tile is done.
 61    /// </summary>
 62    /// <param name="tileId"></param>
 63    /// <returns></returns>
 64    public bool GetTileDone(uint tileId)
 1340465    {
 66        try
 1340467        {
 1340468            _tilesLock.EnterReadLock();
 69
 1340470            return _tiles.Contains(tileId);
 71        }
 72        finally
 1340473        {
 1340474            _tilesLock.ExitReadLock();
 1340475        }
 1340476    }
 77
 78    /// <summary>
 79    /// Returns true if the given edge is on an island.
 80    /// </summary>
 81    /// <param name="edge"></param>
 82    /// <returns></returns>
 83    public bool IsEdgeOnIsland(EdgeId edge)
 7979184    {
 85        try
 7979186        {
 7979187            _islandEdgesLock.EnterReadLock();
 88
 7979189            return _islandEdges.Contains(edge);
 90        }
 91        finally
 7979192        {
 7979193            _islandEdgesLock.ExitReadLock();
 7979194        }
 7979195    }
 96
 97    /// <summary>
 98    /// Marks the given edge as on an island.
 99    /// </summary>
 100    /// <param name="edge"></param>
 101    /// <returns></returns>
 102    public bool SetEdgeOnIsland(EdgeId edge)
 25103    {
 104        try
 25105        {
 25106            _islandEdgesLock.EnterWriteLock();
 107
 25108            return _islandEdges.Add(edge);
 109        }
 110        finally
 25111        {
 25112            _islandEdgesLock.ExitWriteLock();
 25113        }
 25114    }
 115
 116    /// <summary>
 117    /// Kind-aware overload. Reads from <c>_islandEdges</c> for Full and from
 118    /// the transient <c>_nonLocalIslandEdges</c> for NonLocal. The latter is
 119    /// only meaningful while a NonLocal classification pass is in progress
 120    /// or hasn't been collapsed into <c>_localEdges</c> yet.
 121    /// </summary>
 122    public bool IsEdgeOnIsland(EdgeId edge, IslandKind kind)
 70470123    {
 70470124        if (kind == IslandKind.NonLocal)
 70466125        {
 126            try
 70466127            {
 70466128                _nonLocalIslandEdgesLock.EnterReadLock();
 129
 70466130                return _nonLocalIslandEdges.Contains(edge);
 131            }
 132            finally
 70466133            {
 70466134                _nonLocalIslandEdgesLock.ExitReadLock();
 70466135            }
 136        }
 137
 4138        return this.IsEdgeOnIsland(edge);
 70470139    }
 140
 141    /// <summary>
 142    /// Kind-aware overload. Writes to <c>_islandEdges</c> for Full and to the
 143    /// transient <c>_nonLocalIslandEdges</c> for NonLocal.
 144    /// </summary>
 145    public bool SetEdgeOnIsland(EdgeId edge, IslandKind kind)
 33146    {
 33147        if (kind == IslandKind.NonLocal)
 11148        {
 149            try
 11150            {
 11151                _nonLocalIslandEdgesLock.EnterWriteLock();
 152
 11153                return _nonLocalIslandEdges.Add(edge);
 154            }
 155            finally
 11156            {
 11157                _nonLocalIslandEdgesLock.ExitWriteLock();
 11158            }
 159        }
 160
 22161        return this.SetEdgeOnIsland(edge);
 33162    }
 163
 164    /// <summary>
 165    /// Discards the transient <c>_nonLocalIslandEdges</c> set used during
 166    /// NonLocal classification. Called by the build coordinator after
 167    /// <c>_localEdges</c> has been computed from the gap. After this, the
 168    /// only persistent state is <c>_islandEdges</c> and <c>_localEdges</c>.
 169    /// </summary>
 170    internal void ClearNonLocalIslandEdges()
 10171    {
 172        try
 10173        {
 10174            _nonLocalIslandEdgesLock.EnterWriteLock();
 175
 10176            _nonLocalIslandEdges.Clear();
 10177        }
 178        finally
 10179        {
 10180            _nonLocalIslandEdgesLock.ExitWriteLock();
 10181        }
 10182    }
 183
 184    /// <summary>
 185    /// Returns true if the edge is reachable but only via local-access edges —
 186    /// i.e. it is not an island, but every route to it from the main network
 187    /// crosses at least one L-tagged edge first. A typical example is an
 188    /// N-tagged road inside a residential subdivision whose only connection
 189    /// to the main road network goes through an <c>access=destination</c>
 190    /// gate road.
 191    ///
 192    /// L-tagged edges themselves are NOT stored here — they are recognised
 193    /// by their tag, which is build-time information on <c>EdgeFactor</c>.
 194    /// </summary>
 195    public bool IsEdgeLocal(EdgeId edge)
 77356196    {
 197        try
 77356198        {
 77356199            _localEdgesLock.EnterReadLock();
 200
 77356201            return _localEdges.Contains(edge);
 202        }
 203        finally
 77356204        {
 77356205            _localEdgesLock.ExitReadLock();
 77356206        }
 77356207    }
 208
 209    /// <summary>
 210    /// Marks the given edge as reachable only via local-access edges. See
 211    /// <see cref="IsEdgeLocal"/> for what that means.
 212    /// </summary>
 213    public bool SetEdgeLocal(EdgeId edge)
 7214    {
 215        try
 7216        {
 7217            _localEdgesLock.EnterWriteLock();
 218
 7219            return _localEdges.Add(edge);
 220        }
 221        finally
 7222        {
 7223            _localEdgesLock.ExitWriteLock();
 7224        }
 7225    }
 226
 227    internal Islands Clone()
 0228    {
 229        try
 0230        {
 0231            _tilesLock.EnterWriteLock();
 232            try
 0233            {
 0234                _islandEdgesLock.EnterWriteLock();
 235                try
 0236                {
 0237                    _localEdgesLock.EnterWriteLock();
 238
 0239                    return new Islands([.. _tiles], [.. _islandEdges], [.. _localEdges]);
 240                }
 241                finally
 0242                {
 0243                    _localEdgesLock.ExitWriteLock();
 0244                }
 245            }
 246            finally
 0247            {
 0248                _islandEdgesLock.ExitWriteLock();
 0249            }
 250        }
 251        finally
 0252        {
 0253            _tilesLock.ExitWriteLock();
 0254        }
 0255    }
 256}