From 39066900773e7857faf2d02e7ed51b71d219d97d Mon Sep 17 00:00:00 2001 From: godosa Date: Tue, 6 Oct 2026 23:39:36 +0200 Subject: godosa-engine: initial public history --- src/Godosa.Core/Runs/StateDigest.cs | 51 +++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/Godosa.Core/Runs/StateDigest.cs (limited to 'src/Godosa.Core/Runs/StateDigest.cs') diff --git a/src/Godosa.Core/Runs/StateDigest.cs b/src/Godosa.Core/Runs/StateDigest.cs new file mode 100644 index 0000000..a7adaf2 --- /dev/null +++ b/src/Godosa.Core/Runs/StateDigest.cs @@ -0,0 +1,51 @@ +using System.Buffers.Binary; +using System.Text; + +namespace Godosa.Core.Runs; + +/// FNV-1a 64 over state bytes (numbers little-endian, strings UTF-8) for comparing runs. +public sealed class StateDigest +{ + private const ulong Offset = 14695981039346656037UL, Prime = 1099511628211UL; + + public ulong Value { get; private set; } = Offset; + public string Hex => Value.ToString("x16"); + + public static ulong Of(ReadOnlySpan bytes) + { + var d = new StateDigest(); + d.Add(bytes); + return d.Value; + } + + public void Add(ReadOnlySpan bytes) + { + var h = Value; + foreach (var b in bytes) + h = (h ^ b) * Prime; + Value = h; + } + + public void Add(byte b) => Value = (Value ^ b) * Prime; + + public void Add(uint v) + { + Span b = stackalloc byte[4]; + BinaryPrimitives.WriteUInt32LittleEndian(b, v); + Add(b); + } + + public void Add(int v) => Add(unchecked((uint)v)); + + public void Add(ulong v) + { + Span b = stackalloc byte[8]; + BinaryPrimitives.WriteUInt64LittleEndian(b, v); + Add(b); + } + + public void Add(long v) => Add(unchecked((ulong)v)); + public void Add(float v) => Add(BitConverter.SingleToUInt32Bits(v)); + public void Add(double v) => Add(BitConverter.DoubleToUInt64Bits(v)); + public void Add(string s) => Add(Encoding.UTF8.GetBytes(s)); +} -- cgit