Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Marvin.cs
Go to the documentation of this file.
8
9namespace System;
10
11internal static class Marvin
12{
13 public static ulong DefaultSeed { get; } = GenerateSeed();
14
15
16 [MethodImpl(MethodImplOptions.AggressiveInlining)]
17 public static int ComputeHash32(ReadOnlySpan<byte> data, ulong seed)
18 {
19 return ComputeHash32(ref MemoryMarshal.GetReference(data), (uint)data.Length, (uint)seed, (uint)(seed >> 32));
20 }
21
22 public static int ComputeHash32(ref byte data, uint count, uint p0, uint p1)
23 {
24 uint num;
25 if (count < 8)
26 {
27 if (count < 4)
28 {
30 num = 128u;
31 if ((count & (true ? 1u : 0u)) != 0)
32 {
33 num = Unsafe.AddByteOffset(ref data, (nuint)count & (nuint)2u);
35 num |= 0x8000u;
36 }
37 if ((count & 2u) != 0)
38 {
40 num <<= 16;
41 num |= Unsafe.ReadUnaligned<ushort>(ref data);
42 }
43 goto IL_00a6;
44 }
45 }
46 else
47 {
48 uint num2 = count / 8;
49 do
50 {
51 p0 += Unsafe.ReadUnaligned<uint>(ref data);
52 uint num3 = Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref data, 4u));
53 Block(ref p0, ref p1);
54 p0 += num3;
55 Block(ref p0, ref p1);
56 data = ref Unsafe.AddByteOffset(ref data, 8u);
57 }
58 while (--num2 != 0);
59 if ((count & 4) == 0)
60 {
61 goto IL_006a;
62 }
63 }
64 p0 += Unsafe.ReadUnaligned<uint>(ref data);
65 Block(ref p0, ref p1);
66 goto IL_006a;
67 IL_00a6:
68 p0 += num;
69 Block(ref p0, ref p1);
70 Block(ref p0, ref p1);
71 return (int)(p1 ^ p0);
72 IL_006a:
73 num = Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref Unsafe.AddByteOffset(ref data, (nuint)count & (nuint)7u), -4));
74 count = ~count << 3;
76 num >>= 8;
77 num |= 0x80000000u;
78 num >>= (int)(count & 0x1F);
79 goto IL_00a6;
80 }
81
82 [MethodImpl(MethodImplOptions.AggressiveInlining)]
83 private static void Block(ref uint rp0, ref uint rp1)
84 {
85 uint num = rp0;
86 uint num2 = rp1;
87 num2 ^= num;
88 num = BitOperations.RotateLeft(num, 20);
89 num += num2;
90 num2 = BitOperations.RotateLeft(num2, 9);
91 num2 ^= num;
92 num = BitOperations.RotateLeft(num, 27);
93 num += num2;
94 num2 = BitOperations.RotateLeft(num2, 19);
95 rp0 = num;
96 rp1 = num2;
97 }
98
99 private unsafe static ulong GenerateSeed()
100 {
101 System.Runtime.CompilerServices.Unsafe.SkipInit(out ulong result);
102 Interop.GetRandomBytes((byte*)(&result), 8);
103 return result;
104 }
105
106 public static int ComputeHash32OrdinalIgnoreCase(ref char data, int count, uint p0, uint p1)
107 {
108 uint num = (uint)count;
109 nuint num2 = 0u;
110 while (true)
111 {
112 if (num >= 2)
113 {
114 uint value = Unsafe.ReadUnaligned<uint>(ref Unsafe.As<char, byte>(ref Unsafe.AddByteOffset(ref data, num2)));
116 {
117 break;
118 }
120 Block(ref p0, ref p1);
121 num2 += 4;
122 num -= 2;
123 continue;
124 }
125 if (num != 0)
126 {
127 uint value = Unsafe.AddByteOffset(ref data, num2);
128 if (value > 127)
129 {
130 break;
131 }
134 }
136 p0 += 128;
137 Block(ref p0, ref p1);
138 Block(ref p0, ref p1);
139 return (int)(p1 ^ p0);
140 }
141 return ComputeHash32OrdinalIgnoreCaseSlow(ref Unsafe.AddByteOffset(ref data, num2), (int)num, p0, p1);
142 }
143
144 private static int ComputeHash32OrdinalIgnoreCaseSlow(ref char data, int count, uint p0, uint p1)
145 {
146 char[] array = null;
147 Span<char> span = (((uint)count > 64u) ? ((Span<char>)(array = ArrayPool<char>.Shared.Rent(count))) : stackalloc char[64]);
148 Span<char> span2 = span;
149 int num = Ordinal.ToUpperOrdinal(new ReadOnlySpan<char>(ref data, count), span2);
150 int result = ComputeHash32(ref Unsafe.As<char, byte>(ref MemoryMarshal.GetReference(span2)), (uint)(num * 2), p0, p1);
151 if (array != null)
152 {
154 }
155 return result;
156 }
157}
static unsafe void GetRandomBytes(byte *buffer, int length)
Definition Interop.cs:1871
static readonly bool IsLittleEndian
static ArrayPool< T > Shared
Definition ArrayPool.cs:7
T[] Rent(int minimumLength)
static int ToUpperOrdinal(ReadOnlySpan< char > source, Span< char > destination)
Definition Ordinal.cs:193
static ulong DefaultSeed
Definition Marvin.cs:13
static int ComputeHash32(ref byte data, uint count, uint p0, uint p1)
Definition Marvin.cs:22
static int ComputeHash32OrdinalIgnoreCase(ref char data, int count, uint p0, uint p1)
Definition Marvin.cs:106
static void Block(ref uint rp0, ref uint rp1)
Definition Marvin.cs:83
static unsafe ulong GenerateSeed()
Definition Marvin.cs:99
static int ComputeHash32OrdinalIgnoreCaseSlow(ref char data, int count, uint p0, uint p1)
Definition Marvin.cs:144
static int ComputeHash32(ReadOnlySpan< byte > data, ulong seed)
Definition Marvin.cs:17
static uint RotateLeft(uint value, int offset)
static bool AllCharsInUInt32AreAscii(uint value)
static uint ConvertAllAsciiCharsInUInt32ToUppercase(uint value)