< 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:267_28791001112

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.
 449    private readonly ReaderWriterLockSlim _tilesLock = new();
 10    private readonly HashSet<EdgeId> _islandEdges;
 4411    private readonly ReaderWriterLockSlim _islandEdgesLock = new();
 12    private readonly HashSet<EdgeId> _localEdges;
 4413    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;
 4422    private readonly ReaderWriterLockSlim _nonLocalIslandEdgesLock = new();
 23
 4424    internal Islands()
 4425    {
 4426        _tiles = [];
 4427        _islandEdges = [];
 4428        _localEdges = [];
 4429        _nonLocalIslandEdges = [];
 4430    }
 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)
 6446    {
 47        try
 6448        {
 6449            _tilesLock.EnterWriteLock();
 50
 6451            return _tiles.Add(tileId);
 52        }
 53        finally
 6454        {
 6455            _tilesLock.ExitWriteLock();
 6456        }
 6457    }
 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)
 1356565    {
 66        try
 1356567        {
 1356568            _tilesLock.EnterReadLock();
 69
 1356570            return _tiles.Contains(tileId);
 71        }
 72        finally
 1356573        {
 1356574            _tilesLock.ExitReadLock();
 1356575        }
 1356576    }
 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)
 8019184    {
 85        try
 8019186        {
 8019187            _islandEdgesLock.EnterReadLock();
 88
 8019189            return _islandEdges.Contains(edge);
 90        }
 91        finally
 8019192        {
 8019193            _islandEdgesLock.ExitReadLock();
 8019194        }
 8019195    }
 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)
 70770123    {
 70770124        if (kind == IslandKind.NonLocal)
 70766125        {
 126            try
 70766127            {
 70766128                _nonLocalIslandEdgesLock.EnterReadLock();
 129
 70766130                return _nonLocalIslandEdges.Contains(edge);
 131            }
 132            finally
 70766133            {
 70766134                _nonLocalIslandEdgesLock.ExitReadLock();
 70766135            }
 136        }
 137
 4138        return this.IsEdgeOnIsland(edge);
 70770139    }
 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()
 60171    {
 172        try
 60173        {
 60174            _nonLocalIslandEdgesLock.EnterWriteLock();
 175
 60176            _nonLocalIslandEdges.Clear();
 60177        }
 178        finally
 60179        {
 60180            _nonLocalIslandEdgesLock.ExitWriteLock();
 60181        }
 60182    }
 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)
 77556196    {
 197        try
 77556198        {
 77556199            _localEdgesLock.EnterReadLock();
 200
 77556201            return _localEdges.Contains(edge);
 202        }
 203        finally
 77556204        {
 77556205            _localEdgesLock.ExitReadLock();
 77556206        }
 77556207    }
 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}