Skip to content

Commit f1870cd

Browse files
authored
refactor: replace 3rd-party xxhash impl with in-house reimpl (#2310)
1 parent 0b0679d commit f1870cd

File tree

11 files changed

+300
-396
lines changed

11 files changed

+300
-396
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
# Changelog
32

43
All notable changes to this project will be documented in this file.
@@ -10,11 +9,13 @@ Additional documentation and release notes are available at [Multiplayer Documen
109
## [Unreleased]
1110

1211
### Added
12+
1313
- Added `NetworkObject` auto-add helper and Multiplayer Tools install reminder settings to Project Settings. (#2285)
1414
- Added `public string DisconnectReason` getter to `NetworkManager` and `string Reason` to `ConnectionApprovalResponse`. Allows connection approval to communicate back a reason. Also added `public void DisconnectClient(ulong clientId, string reason)` allowing setting a disconnection reason, when explicitly disconnecting a client.
1515

1616
### Changed
1717

18+
- Changed 3rd-party `XXHash` (32 & 64) implementation with an in-house reimplementation (#2310)
1819
- Optimized bandwidth usage by encoding most integer fields using variable-length encoding. (#2276)
1920

2021
### Fixed
@@ -25,9 +26,10 @@ Additional documentation and release notes are available at [Multiplayer Documen
2526
- Fixed issue where in-scene placed `NetworkObjects` were not honoring the `AutoObjectParentSync` property. (#2281)
2627
- Fixed the issue where `NetworkManager.OnClientConnectedCallback` was being invoked before in-scene placed `NetworkObject`s had been spawned when starting `NetworkManager` as a host. (#2277)
2728
- Creating a `FastBufferReader` with `Allocator.None` will not result in extra memory being allocated for the buffer (since it's owned externally in that scenario). (#2265)
29+
2830
### Removed
29-
- Removed the `NetworkObject` auto-add and Multiplayer Tools install reminder settings from the Menu interface. (#2285)
3031

32+
- Removed the `NetworkObject` auto-add and Multiplayer Tools install reminder settings from the Menu interface. (#2285)
3133

3234
## [1.1.0] - 2022-10-21
3335

@@ -179,6 +181,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
179181
- Removed `ClientNetworkTransform` from the package samples and moved to Boss Room's Utilities package which can be found [here](https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop/blob/main/Packages/com.unity.multiplayer.samples.coop/Utilities/Net/ClientAuthority/ClientNetworkTransform.cs) (#1912)
180182

181183
### Fixed
184+
182185
- Fixed issue where `NetworkSceneManager` did not synchronize despawned in-scene placed NetworkObjects. (#1898)
183186
- Fixed `NetworkTransform` generating false positive rotation delta checks when rolling over between 0 and 360 degrees. (#1890)
184187
- Fixed client throwing an exception if it has messages in the outbound queue when processing the `NetworkEvent.Disconnect` event and is using UTP. (#1884)
@@ -232,10 +235,12 @@ Additional documentation and release notes are available at [Multiplayer Documen
232235
## [1.0.0-pre.6] - 2022-03-02
233236

234237
### Added
238+
235239
- NetworkAnimator now properly synchrhonizes all animation layers as well as runtime-adjusted weighting between them (#1765)
236240
- Added first set of tests for NetworkAnimator - parameter syncing, trigger set / reset, override network animator (#1735)
237241

238242
### Fixed
243+
239244
- Fixed an issue where sometimes the first client to connect to the server could see messages from the server as coming from itself. (#1683)
240245
- Fixed an issue where clients seemed to be able to send messages to ClientId 1, but these messages would actually still go to the server (id 0) instead of that client. (#1683)
241246
- Improved clarity of error messaging when a client attempts to send a message to a destination other than the server, which isn't allowed. (#1683)
@@ -287,6 +292,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
287292
- Removed `FixedQueue`, `StreamExtensions`, `TypeExtensions` (#1398)
288293

289294
### Fixed
295+
290296
- Fixed in-scene NetworkObjects that are moved into the DDOL scene not getting restored to their original active state (enabled/disabled) after a full scene transition (#1354)
291297
- Fixed invalid IL code being generated when using `this` instead of `this ref` for the FastBufferReader/FastBufferWriter parameter of an extension method. (#1393)
292298
- Fixed an issue where if you are running as a server (not host) the LoadEventCompleted and UnloadEventCompleted events would fire early by the NetworkSceneManager (#1379)
@@ -301,6 +307,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
301307
- Fixed network tick value sometimes being duplicated or skipped. (#1614)
302308

303309
### Changed
310+
304311
- The SDK no longer limits message size to 64k. (The transport may still impose its own limits, but the SDK no longer does.) (#1384)
305312
- Updated com.unity.collections to 1.1.0 (#1451)
306313
- NetworkManager's GameObject is no longer allowed to be nested under one or more GameObject(s).(#1484)
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
using System;
2+
using System.Text;
3+
using System.Runtime.CompilerServices;
4+
5+
namespace Unity.Netcode
6+
{
7+
internal static class XXHash
8+
{
9+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
10+
public static unsafe uint Hash32(byte* input, int length, uint seed = 0)
11+
{
12+
unchecked
13+
{
14+
const uint prime1 = 2654435761u;
15+
const uint prime2 = 2246822519u;
16+
const uint prime3 = 3266489917u;
17+
const uint prime4 = 0668265263u;
18+
const uint prime5 = 0374761393u;
19+
20+
uint hash = seed + prime5;
21+
22+
if (length >= 16)
23+
{
24+
uint val0 = seed + prime1 + prime2;
25+
uint val1 = seed + prime2;
26+
uint val2 = seed + 0;
27+
uint val3 = seed - prime1;
28+
29+
int count = length >> 4;
30+
for (int i = 0; i < count; i++)
31+
{
32+
var pos0 = *(uint*)(input + 0);
33+
var pos1 = *(uint*)(input + 4);
34+
var pos2 = *(uint*)(input + 8);
35+
var pos3 = *(uint*)(input + 12);
36+
37+
val0 += pos0 * prime2;
38+
val0 = (val0 << 13) | (val0 >> (32 - 13));
39+
val0 *= prime1;
40+
41+
val1 += pos1 * prime2;
42+
val1 = (val1 << 13) | (val1 >> (32 - 13));
43+
val1 *= prime1;
44+
45+
val2 += pos2 * prime2;
46+
val2 = (val2 << 13) | (val2 >> (32 - 13));
47+
val2 *= prime1;
48+
49+
val3 += pos3 * prime2;
50+
val3 = (val3 << 13) | (val3 >> (32 - 13));
51+
val3 *= prime1;
52+
53+
input += 16;
54+
}
55+
56+
hash = ((val0 << 01) | (val0 >> (32 - 01))) +
57+
((val1 << 07) | (val1 >> (32 - 07))) +
58+
((val2 << 12) | (val2 >> (32 - 12))) +
59+
((val3 << 18) | (val3 >> (32 - 18)));
60+
}
61+
62+
hash += (uint)length;
63+
64+
length &= 15;
65+
while (length >= 4)
66+
{
67+
hash += *(uint*)input * prime3;
68+
hash = ((hash << 17) | (hash >> (32 - 17))) * prime4;
69+
input += 4;
70+
length -= 4;
71+
}
72+
while (length > 0)
73+
{
74+
hash += *input * prime5;
75+
hash = ((hash << 11) | (hash >> (32 - 11))) * prime1;
76+
++input;
77+
--length;
78+
}
79+
80+
hash ^= hash >> 15;
81+
hash *= prime2;
82+
hash ^= hash >> 13;
83+
hash *= prime3;
84+
hash ^= hash >> 16;
85+
86+
return hash;
87+
}
88+
}
89+
90+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
91+
public static unsafe ulong Hash64(byte* input, int length, uint seed = 0)
92+
{
93+
unchecked
94+
{
95+
const ulong prime1 = 11400714785074694791ul;
96+
const ulong prime2 = 14029467366897019727ul;
97+
const ulong prime3 = 01609587929392839161ul;
98+
const ulong prime4 = 09650029242287828579ul;
99+
const ulong prime5 = 02870177450012600261ul;
100+
101+
ulong hash = seed + prime5;
102+
103+
if (length >= 32)
104+
{
105+
ulong val0 = seed + prime1 + prime2;
106+
ulong val1 = seed + prime2;
107+
ulong val2 = seed + 0;
108+
ulong val3 = seed - prime1;
109+
110+
int count = length >> 5;
111+
for (int i = 0; i < count; i++)
112+
{
113+
var pos0 = *(ulong*)(input + 0);
114+
var pos1 = *(ulong*)(input + 8);
115+
var pos2 = *(ulong*)(input + 16);
116+
var pos3 = *(ulong*)(input + 24);
117+
118+
val0 += pos0 * prime2;
119+
val0 = (val0 << 31) | (val0 >> (64 - 31));
120+
val0 *= prime1;
121+
122+
val1 += pos1 * prime2;
123+
val1 = (val1 << 31) | (val1 >> (64 - 31));
124+
val1 *= prime1;
125+
126+
val2 += pos2 * prime2;
127+
val2 = (val2 << 31) | (val2 >> (64 - 31));
128+
val2 *= prime1;
129+
130+
val3 += pos3 * prime2;
131+
val3 = (val3 << 31) | (val3 >> (64 - 31));
132+
val3 *= prime1;
133+
134+
input += 32;
135+
}
136+
137+
hash = ((val0 << 01) | (val0 >> (64 - 01))) +
138+
((val1 << 07) | (val1 >> (64 - 07))) +
139+
((val2 << 12) | (val2 >> (64 - 12))) +
140+
((val3 << 18) | (val3 >> (64 - 18)));
141+
142+
val0 *= prime2;
143+
val0 = (val0 << 31) | (val0 >> (64 - 31));
144+
val0 *= prime1;
145+
hash ^= val0;
146+
hash = hash * prime1 + prime4;
147+
148+
val1 *= prime2;
149+
val1 = (val1 << 31) | (val1 >> (64 - 31));
150+
val1 *= prime1;
151+
hash ^= val1;
152+
hash = hash * prime1 + prime4;
153+
154+
val2 *= prime2;
155+
val2 = (val2 << 31) | (val2 >> (64 - 31));
156+
val2 *= prime1;
157+
hash ^= val2;
158+
hash = hash * prime1 + prime4;
159+
160+
val3 *= prime2;
161+
val3 = (val3 << 31) | (val3 >> (64 - 31));
162+
val3 *= prime1;
163+
hash ^= val3;
164+
hash = hash * prime1 + prime4;
165+
}
166+
167+
hash += (ulong)length;
168+
169+
length &= 31;
170+
while (length >= 8)
171+
{
172+
ulong lane = *(ulong*)input * prime2;
173+
lane = ((lane << 31) | (lane >> (64 - 31))) * prime1;
174+
hash ^= lane;
175+
hash = ((hash << 27) | (hash >> (64 - 27))) * prime1 + prime4;
176+
input += 8;
177+
length -= 8;
178+
}
179+
if (length >= 4)
180+
{
181+
hash ^= *(uint*)input * prime1;
182+
hash = ((hash << 23) | (hash >> (64 - 23))) * prime2 + prime3;
183+
input += 4;
184+
length -= 4;
185+
}
186+
while (length > 0)
187+
{
188+
hash ^= *input * prime5;
189+
hash = ((hash << 11) | (hash >> (64 - 11))) * prime1;
190+
++input;
191+
--length;
192+
}
193+
194+
hash ^= hash >> 33;
195+
hash *= prime2;
196+
hash ^= hash >> 29;
197+
hash *= prime3;
198+
hash ^= hash >> 32;
199+
200+
return hash;
201+
}
202+
}
203+
204+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
205+
public static uint Hash32(this byte[] buffer)
206+
{
207+
int length = buffer.Length;
208+
unsafe
209+
{
210+
fixed (byte* pointer = buffer)
211+
{
212+
return Hash32(pointer, length);
213+
}
214+
}
215+
}
216+
217+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
218+
public static uint Hash32(this string text) => Hash32(Encoding.UTF8.GetBytes(text));
219+
220+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
221+
public static uint Hash32(this Type type) => Hash32(type.FullName);
222+
223+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
224+
public static uint Hash32<T>() => Hash32(typeof(T));
225+
226+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
227+
public static ulong Hash64(this byte[] buffer)
228+
{
229+
int length = buffer.Length;
230+
unsafe
231+
{
232+
fixed (byte* pointer = buffer)
233+
{
234+
return Hash64(pointer, length);
235+
}
236+
}
237+
}
238+
239+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
240+
public static ulong Hash64(this string text) => Hash64(Encoding.UTF8.GetBytes(text));
241+
242+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
243+
public static ulong Hash64(this Type type) => Hash64(type.FullName);
244+
245+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
246+
public static ulong Hash64<T>() => Hash64(typeof(T));
247+
}
248+
}

com.unity.netcode.gameobjects/Runtime/Hashing/XXHash/XXHash.cs.meta renamed to com.unity.netcode.gameobjects/Runtime/Hashing/XXHash.cs.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

com.unity.netcode.gameobjects/Runtime/Hashing/XXHash.meta

Lines changed: 0 additions & 8 deletions
This file was deleted.

com.unity.netcode.gameobjects/Runtime/Hashing/XXHash/LICENSE

Lines changed: 0 additions & 21 deletions
This file was deleted.

com.unity.netcode.gameobjects/Runtime/Hashing/XXHash/LICENSE.meta

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)