Class StableHash
Utility methods for persisted cache keys.
public static class StableHash
- Inheritance
-
StableHash
- Inherited Members
Remarks
Everything here is deterministic across processes, runtimes and .NET versions (on little-endian platforms), because the results are persisted. Hash values are a serialisation contract: changing them requires a CacheFile format version bump. The golden tests pin them.
Methods
Combine(int, int)
Stably combines two hash codes, a fixed-seed counterpart to Combine<T1, T2>(T1, T2).
public static int Combine(int hash1, int hash2)
Parameters
Returns
Combine(int, int, int)
Stably combines three hash codes, a fixed-seed counterpart to Combine<T1, T2, T3>(T1, T2, T3).
public static int Combine(int hash1, int hash2, int hash3)
Parameters
Returns
ForBytes(ReadOnlySpan<byte>)
Produces a stable hash code for raw bytes using the Marvin32 algorithm with a fixed seed.
public static int ForBytes(ReadOnlySpan<byte> data)
Parameters
dataReadOnlySpan<byte>
Returns
ForGuid(Guid)
Produces a stable hash code for a guid, independent of GetHashCode().
public static int ForGuid(Guid guid)
Parameters
guidGuid
Returns
ForString(string?)
Produces a stable hash code using the Marvin32 algorithm (which GetHashCode() does not).
public static int ForString(string? str)
Parameters
strstring
Returns
Remarks
This implementation is based on .NET's Marvin hashing algorithm but uses a fixed seed to ensure stability. .NET's string.GetHashCode() uses a randomized seed to prevent hash-based attacks, but we need stable hashes for caching.
ForValue(object?)
Produces a stable hash code for a query constant, covering the closed domain of value types the query analyzer admits: the ValueBox types, RelativeDate, enums, and sequences of any of these. Values outside the domain fall back to their own GetHashCode(), which is process-local.
public static int ForValue(object? value)
Parameters
valueobject
Returns
Remarks
Equal values must hash equal, so each recipe follows its type's equality semantics: DateTime equality ignores Kind, DateTimeOffset equality compares UTC instants, -0.0 equals 0.0, NaN equals NaN, and numerically-equal decimals of different scale are equal.