36 lines
1.3 KiB
C#
36 lines
1.3 KiB
C#
namespace ScadaLink.SiteRuntime.Repositories;
|
|
|
|
/// <summary>
|
|
/// SiteRuntime-007: deterministic synthetic-ID generation for site-local artifacts.
|
|
///
|
|
/// The site SQLite tables are keyed by name rather than an auto-increment integer, but
|
|
/// the shared repository contracts (<c>IExternalSystemRepository</c>,
|
|
/// <c>INotificationRepository</c>) expose integer-keyed lookups. A synthetic integer ID
|
|
/// is therefore derived from the entity name. It MUST be stable across process restarts
|
|
/// — <see cref="string.GetHashCode()"/> is randomized per process on .NET Core and so
|
|
/// cannot be used.
|
|
/// </summary>
|
|
internal static class SyntheticId
|
|
{
|
|
// FNV-1a 32-bit constants.
|
|
private const uint FnvOffsetBasis = 2166136261;
|
|
private const uint FnvPrime = 16777619;
|
|
|
|
/// <summary>
|
|
/// Computes a deterministic, process-stable positive 31-bit integer ID for the
|
|
/// given name using the FNV-1a hash over its UTF-8 bytes.
|
|
/// </summary>
|
|
public static int From(string name)
|
|
{
|
|
var hash = FnvOffsetBasis;
|
|
foreach (var b in System.Text.Encoding.UTF8.GetBytes(name))
|
|
{
|
|
hash ^= b;
|
|
hash *= FnvPrime;
|
|
}
|
|
|
|
// Mask to a positive 31-bit value so the ID is always non-negative.
|
|
return (int)(hash & 0x7FFFFFFF);
|
|
}
|
|
}
|