< Summary

Information
Class: Trailblazer.Pathing.NavigationAStarNodeTable
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Search/AStar/NavigationAStarNodeTable.cs
Line coverage
100%
Covered lines: 34
Uncovered lines: 0
Coverable lines: 34
Total lines: 96
Line coverage: 100%
Branch coverage
100%
Covered branches: 10
Total branches: 10
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%22100%
Reset()100%11100%
TryGetSlot(...)100%44100%
TryGetOrAdd(...)100%44100%
GetRecord(...)100%11100%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Search/AStar/NavigationAStarNodeTable.cs

#LineLine coverage
 1//=======================================================================
 2// NavigationAStarNodeTable.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2024-present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using System;
 9using FixedMathSharp;
 10
 11namespace Trailblazer.Pathing;
 12
 13internal struct NavigationAStarNodeRecord
 14{
 15    internal Fixed64 Cost;
 16    internal Fixed64 Heuristic;
 17    // The search-only f-score adds eight bytes per workspace node, never to cached payloads.
 18    internal Fixed64 EstimatedTotalCost;
 19    internal NavigationMediumStateRef Parent;
 20    internal NavigationTraversalEdgeKind ParentEdgeKind;
 21    internal int HeapIndex;
 22    internal int ParentEdgeOrdinal;
 23    internal bool HasParent;
 24    internal bool Closed;
 25}
 26
 27/// <summary>Stores fixed-capacity generation-stamped A* metadata.</summary>
 28internal sealed class NavigationAStarNodeTable
 29{
 30    private readonly NavigationMediumStateRef[] _keys;
 31    private readonly NavigationAStarNodeRecord[] _records;
 32    private readonly long[] _stamps;
 33    private readonly int _mask;
 34    private readonly int _capacity;
 35    private int _count;
 805336    private long _generation = 1;
 37
 805338    internal NavigationAStarNodeTable(int capacity)
 39    {
 805340        int tableSize = 1;
 805341        int required = checked(Math.Max(1, capacity * 2));
 11052742        while (tableSize < required)
 10247443            tableSize = checked(tableSize * 2);
 805344        _keys = new NavigationMediumStateRef[tableSize];
 805345        _records = new NavigationAStarNodeRecord[tableSize];
 805346        _stamps = new long[tableSize];
 805347        _mask = tableSize - 1;
 805348        _capacity = capacity;
 805349    }
 50
 51    internal void Reset()
 52    {
 53        unchecked
 54        {
 25255            _generation++;
 56        }
 25257        _count = 0;
 25258    }
 59
 60    internal bool TryGetSlot(NavigationMediumStateRef node, out int slot)
 61    {
 7624862        slot = node.GetHashCode() & _mask;
 7629163        while (_stamps[slot] == _generation)
 64        {
 7039665            if (_keys[slot].Equals(node))
 7035366                return true;
 4367            slot = (slot + 1) & _mask;
 68        }
 589569        return false;
 70    }
 71
 72    internal bool TryGetOrAdd(
 73        NavigationMediumStateRef node,
 74        out int slot,
 75        out bool added)
 76    {
 504577        if (TryGetSlot(node, out slot))
 78        {
 197679            added = false;
 197680            return true;
 81        }
 306982        if (_count >= _capacity)
 83        {
 284            added = false;
 285            return false;
 86        }
 306787        _keys[slot] = node;
 306788        _records[slot] = default;
 306789        _stamps[slot] = _generation;
 306790        _count++;
 306791        added = true;
 306792        return true;
 93    }
 94
 7648495    internal ref NavigationAStarNodeRecord GetRecord(int slot) => ref _records[slot];
 96}