66 lines
3.9 KiB
C#
66 lines
3.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace MultiWheelC.TrajectoryPlanning.Mapping;
|
|
|
|
/// <summary>线程安全、容量为四的 LRU 缓存,分别复用精确输入结果和不可变占据数组。</summary>
|
|
internal sealed class PlanningMapCache
|
|
{
|
|
private const int Capacity = 4;
|
|
private readonly object _gate = new object();
|
|
private readonly LinkedList<InputEntry> _inputs = new LinkedList<InputEntry>();
|
|
private readonly LinkedList<OccupancyEntry> _occupancies = new LinkedList<OccupancyEntry>();
|
|
|
|
/// <summary>按完整输入描述查询缓存。命中时返回原始快照与来源结果,并提升其最近使用顺序。</summary>
|
|
public bool TryGetInput(string descriptor, out PlanningGridMap map, out IReadOnlyList<ObstacleProjectionResult> sourceResults)
|
|
{
|
|
lock (_gate)
|
|
{
|
|
for (var node = _inputs.First; node != null; node = node.Next)
|
|
if (string.Equals(node.Value.Descriptor, descriptor, StringComparison.Ordinal))
|
|
{ map = node.Value.Map; sourceResults = node.Value.SourceResults; _inputs.Remove(node); _inputs.AddFirst(node); return true; }
|
|
map = null; sourceResults = null; return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>按占据哈希及逐格比较查询缓存。命中时返回共享数组的规范快照,供工厂创建新的元数据快照。</summary>
|
|
public bool TryGetOccupancy(string hash, PlanningGridMap candidate, out PlanningGridMap canonical)
|
|
{
|
|
lock (_gate)
|
|
{
|
|
for (var node = _occupancies.First; node != null; node = node.Next)
|
|
if (string.Equals(node.Value.Hash, hash, StringComparison.Ordinal) && node.Value.Map.OccupancyEquals(candidate))
|
|
{ canonical = node.Value.Map; _occupancies.Remove(node); _occupancies.AddFirst(node); return true; }
|
|
canonical = null; return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>写入或更新精确输入缓存。参数 descriptor 为完整输入键,map 为不可变快照,sourceResults 为对应来源结果。</summary>
|
|
public void AddInput(string descriptor, PlanningGridMap map, IReadOnlyList<ObstacleProjectionResult> sourceResults)
|
|
{
|
|
lock (_gate)
|
|
{
|
|
for (var node = _inputs.First; node != null; node = node.Next)
|
|
if (string.Equals(node.Value.Descriptor, descriptor, StringComparison.Ordinal)) { node.Value.Map = map; node.Value.SourceResults = sourceResults; _inputs.Remove(node); _inputs.AddFirst(node); return; }
|
|
_inputs.AddFirst(new InputEntry(descriptor, map, sourceResults));
|
|
while (_inputs.Count > Capacity) _inputs.RemoveLast();
|
|
}
|
|
}
|
|
|
|
/// <summary>写入占据缓存。参数 hash 为占据内容哈希,map 为包含可复用占据与距离数组的快照。</summary>
|
|
public void AddOccupancy(string hash, PlanningGridMap map)
|
|
{
|
|
lock (_gate)
|
|
{
|
|
for (var node = _occupancies.First; node != null; node = node.Next)
|
|
if (string.Equals(node.Value.Hash, hash, StringComparison.Ordinal) && node.Value.Map.OccupancyEquals(map))
|
|
{ _occupancies.Remove(node); _occupancies.AddFirst(node); return; }
|
|
_occupancies.AddFirst(new OccupancyEntry(hash, map));
|
|
while (_occupancies.Count > Capacity) _occupancies.RemoveLast();
|
|
}
|
|
}
|
|
|
|
private sealed class InputEntry { public InputEntry(string descriptor, PlanningGridMap map, IReadOnlyList<ObstacleProjectionResult> sourceResults) { Descriptor = descriptor; Map = map; SourceResults = sourceResults; } public string Descriptor { get; } public PlanningGridMap Map { get; set; } public IReadOnlyList<ObstacleProjectionResult> SourceResults { get; set; } }
|
|
private sealed class OccupancyEntry { public OccupancyEntry(string hash, PlanningGridMap map) { Hash = hash; Map = map; } public string Hash { get; } public PlanningGridMap Map { get; } }
|
|
}
|