using Mbproxy.Proxy.Multiplexing;

namespace Mbproxy.Proxy.Cache;

/// <summary>
/// Hash key for the per-PLC <see cref="ResponseCache"/>. Structurally identical to
/// the read-coalescing <see cref="CoalescingKey"/> — both keys discriminate the same
/// dimensions (UnitId, FunctionCode, StartAddress, Quantity), but the two type aliases
/// live in different namespaces so the cache and the coalescer can evolve independently
/// without one shaping the other's API surface.
///
/// <para><b>Equality semantics:</b> record-struct value equality. FC03 and FC04 produce
/// different keys for the same address (different Modbus tables); different
/// <see cref="UnitId"/> bytes never share a key (different PLC personalities behind a
/// shared socket); reads of different <see cref="Qty"/> never share a key (the responses
/// carry different register counts and would not be interchangeable on a fan-out).</para>
///
/// <para><b>Scope:</b> only FC03 (Read Holding Registers) and FC04 (Read Input Registers)
/// are cacheable. FC06 / FC16 writes invalidate cache entries by ADDRESS RANGE OVERLAP
/// rather than exact-key match — see <see cref="CacheInvalidator"/>.</para>
/// </summary>
internal readonly record struct CacheKey(
    byte UnitId,
    byte Fc,
    ushort StartAddress,
    ushort Qty);
