Skip to content

Commit 6c6ee89

Browse files
committed
Reworked internals: minor changes
1 parent dd31ee7 commit 6c6ee89

15 files changed

+90
-24
lines changed

src/ZstdSharp/Polyfills/BitOperations.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,54 @@ public static uint RotateRight(uint value, int offset)
195195
[MethodImpl(MethodImplOptions.AggressiveInlining)]
196196
public static ulong RotateRight(ulong value, int offset)
197197
=> (value >> offset) | (value << (64 - offset));
198+
199+
/// <summary>
200+
/// Count the number of leading zero bits in a mask.
201+
/// Similar in behavior to the x86 instruction LZCNT.
202+
/// </summary>
203+
/// <param name="value">The value.</param>
204+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
205+
public static int LeadingZeroCount(uint value)
206+
{
207+
// Unguarded fallback contract is 0->31, BSR contract is 0->undefined
208+
if (value == 0)
209+
{
210+
return 32;
211+
}
212+
213+
// No AggressiveInlining due to large method size
214+
// Has conventional contract 0->0 (Log(0) is undefined)
215+
216+
// Fill trailing zeros with ones, eg 00010010 becomes 00011111
217+
value |= value >> 01;
218+
value |= value >> 02;
219+
value |= value >> 04;
220+
value |= value >> 08;
221+
value |= value >> 16;
222+
223+
// uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check
224+
return 31 ^ Log2DeBruijn[
225+
// uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here
226+
(int)((value * 0x07C4ACDDu) >> 27)];
227+
}
228+
229+
/// <summary>
230+
/// Count the number of leading zero bits in a mask.
231+
/// Similar in behavior to the x86 instruction LZCNT.
232+
/// </summary>
233+
/// <param name="value">The value.</param>
234+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
235+
public static int LeadingZeroCount(ulong value)
236+
{
237+
uint hi = (uint)(value >> 32);
238+
239+
if (hi == 0)
240+
{
241+
return 32 + LeadingZeroCount((uint)value);
242+
}
243+
244+
return LeadingZeroCount(hi);
245+
}
198246
}
199247
}
200248

src/ZstdSharp/ThrowHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ public static unsafe class ThrowHelper
99

1010
public static nuint EnsureZstdSuccess(this nuint returnValue)
1111
{
12-
if (Methods.ZSTD_isError(returnValue) != 0)
12+
if (Methods.ZSTD_isError(returnValue))
1313
ThrowException(returnValue, Methods.ZSTD_getErrorName(returnValue));
1414

1515
return returnValue;
1616
}
1717

1818
public static nuint EnsureZdictSuccess(this nuint returnValue)
1919
{
20-
if (Methods.ZDICT_isError(returnValue) != 0)
20+
if (Methods.ZDICT_isError(returnValue))
2121
ThrowException(returnValue, Methods.ZDICT_getErrorName(returnValue));
2222

2323
return returnValue;

src/ZstdSharp/Unsafe/Clevels.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using static ZstdSharp.UnsafeHelper;
2-
31
namespace ZstdSharp.Unsafe
42
{
53
public static unsafe partial class Methods

src/ZstdSharp/Unsafe/Cover.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ public static COVER_dictSelection COVER_selectDict(byte* customDictContent, nuin
279279

280280
memcpy(largestDictbuffer, customDictContent, (uint)dictContentSize);
281281
dictContentSize = ZDICT_finalizeDictionary(largestDictbuffer, dictBufferCapacity, customDictContent, dictContentSize, samplesBuffer, samplesSizes, nbFinalizeSamples, @params.zParams);
282-
if (ZDICT_isError(dictContentSize) != 0)
282+
if (ZDICT_isError(dictContentSize))
283283
{
284284
free(largestDictbuffer);
285285
free(candidateDictBuffer);
@@ -308,7 +308,7 @@ public static COVER_dictSelection COVER_selectDict(byte* customDictContent, nuin
308308
{
309309
memcpy(candidateDictBuffer, largestDictbuffer, (uint)largestDict);
310310
dictContentSize = ZDICT_finalizeDictionary(candidateDictBuffer, dictBufferCapacity, customDictContentEnd - dictContentSize, dictContentSize, samplesBuffer, samplesSizes, nbFinalizeSamples, @params.zParams);
311-
if (ZDICT_isError(dictContentSize) != 0)
311+
if (ZDICT_isError(dictContentSize))
312312
{
313313
free(largestDictbuffer);
314314
free(candidateDictBuffer);

src/ZstdSharp/Unsafe/EntropyCommon.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using System.Runtime.CompilerServices;
21
using static ZstdSharp.UnsafeHelper;
2+
using System.Runtime.CompilerServices;
33
using System.Numerics;
44

55
namespace ZstdSharp.Unsafe

src/ZstdSharp/Unsafe/ErrorPrivate.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Runtime.CompilerServices;
2-
using static ZstdSharp.UnsafeHelper;
32

43
namespace ZstdSharp.Unsafe
54
{

src/ZstdSharp/Unsafe/Fastcover.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ public static nuint ZDICT_optimizeTrainFromBuffer_fastCover(void* dictBuffer, nu
555555
}
556556

557557
COVER_best_start(&best);
558-
if (!(pool != null))
558+
if (pool == null)
559559
{
560560
FASTCOVER_tryParameters(data);
561561
}

src/ZstdSharp/Unsafe/Hist.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ namespace ZstdSharp.Unsafe
55
public static unsafe partial class Methods
66
{
77
/* --- Error management --- */
8-
public static uint HIST_isError(nuint code)
8+
public static bool HIST_isError(nuint code)
99
{
10-
return ERR_isError(code) ? 1U : 0U;
10+
return ERR_isError(code);
1111
}
1212

1313
/*-**************************************************************

src/ZstdSharp/Unsafe/Zdict.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ public static unsafe partial class Methods
77
/*-********************************************************
88
* Helper functions
99
**********************************************************/
10-
public static uint ZDICT_isError(nuint errorCode)
10+
public static bool ZDICT_isError(nuint errorCode)
1111
{
12-
return ERR_isError(errorCode) ? 1U : 0U;
12+
return ERR_isError(errorCode);
1313
}
1414

1515
public static string ZDICT_getErrorName(nuint errorCode)
@@ -385,7 +385,7 @@ public static nuint ZDICT_finalizeDictionary(void* dictBuffer, nuint dictBufferC
385385
hSize = 8;
386386
{
387387
nuint eSize = ZDICT_analyzeEntropy(header + hSize, 256 - hSize, compressionLevel, samplesBuffer, samplesSizes, nbSamples, customDictContent, dictContentSize, notificationLevel);
388-
if (ZDICT_isError(eSize) != 0)
388+
if (ZDICT_isError(eSize))
389389
return eSize;
390390
hSize += eSize;
391391
}
@@ -434,7 +434,7 @@ private static nuint ZDICT_addEntropyTablesFromBuffer_advanced(void* dictBuffer,
434434
nuint hSize = 8;
435435
{
436436
nuint eSize = ZDICT_analyzeEntropy((sbyte*)dictBuffer + hSize, dictBufferCapacity - hSize, compressionLevel, samplesBuffer, samplesSizes, nbSamples, (sbyte*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize, notificationLevel);
437-
if (ZDICT_isError(eSize) != 0)
437+
if (ZDICT_isError(eSize))
438438
return eSize;
439439
hSize += eSize;
440440
}

src/ZstdSharp/Unsafe/Zstd.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using static ZstdSharp.UnsafeHelper;
2-
31
namespace ZstdSharp.Unsafe
42
{
53
public static unsafe partial class Methods

src/ZstdSharp/Unsafe/ZstdCommon.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ public static string ZSTD_versionString()
2222
/*! ZSTD_isError() :
2323
* tells if a return value is an error code
2424
* symbol is required for external callers */
25-
public static uint ZSTD_isError(nuint code)
25+
public static bool ZSTD_isError(nuint code)
2626
{
27-
return ERR_isError(code) ? 1U : 0U;
27+
return ERR_isError(code);
2828
}
2929

3030
/*! ZSTD_getErrorName() :

src/ZstdSharp/Unsafe/ZstdCompress.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2199,7 +2199,7 @@ private static nuint ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx_s* cctx, ZSTD_CDi
21992199
{
22002200
uint cdictEnd = (uint)(cdict->matchState.window.nextSrc - cdict->matchState.window.@base);
22012201
uint cdictLen = cdictEnd - cdict->matchState.window.dictLimit;
2202-
if (!(cdictLen == 0))
2202+
if (cdictLen != 0)
22032203
{
22042204
cctx->blockState.matchState.dictMatchState = &cdict->matchState;
22052205
if (cctx->blockState.matchState.window.dictLimit < cdictEnd)

src/ZstdSharp/Unsafe/ZstdCompressInternal.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,10 @@ private static uint ZSTD_NbCommonBytes(nuint val)
225225
assert(val != 0);
226226
if (BitConverter.IsLittleEndian)
227227
{
228-
return (uint)(BitOperations.TrailingZeroCount(val) >> 3);
228+
return MEM_64bits ? (uint)BitOperations.TrailingZeroCount(val) >> 3 : (uint)BitOperations.TrailingZeroCount((uint)val) >> 3;
229229
}
230230

231-
return (uint)(BitOperations.Log2(val) >> 3);
231+
return MEM_64bits ? (uint)BitOperations.LeadingZeroCount(val) >> 3 : (uint)BitOperations.LeadingZeroCount((uint)val) >> 3;
232232
}
233233

234234
[MethodImpl(MethodImplOptions.AggressiveInlining)]

src/ZstdSharp/Unsafe/ZstdInternal.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#endif
55
using System.Runtime.CompilerServices;
66
using System.Numerics;
7+
#if NET5_0_OR_GREATER
8+
using System.Runtime.Intrinsics.Arm;
9+
#endif
710

811
namespace ZstdSharp.Unsafe
912
{
@@ -33,9 +36,29 @@ private static void ZSTD_copy8(void* dst, void* src)
3336
the dst buffer. In circumstances where the op "catches up" to where the
3437
literal buffer is, there can be partial overlaps in this call on the final
3538
copy if the literal is being shifted by less than 16 bytes. */
39+
[InlineMethod.Inline]
3640
private static void ZSTD_copy16(void* dst, void* src)
3741
{
38-
memcpy(dst, src, 16);
42+
#if NET5_0_OR_GREATER
43+
if (AdvSimd.IsSupported)
44+
{
45+
AdvSimd.Store((byte*)dst, AdvSimd.LoadVector128((byte*)src));
46+
}
47+
else
48+
#endif
49+
#if NETCOREAPP3_0_OR_GREATER
50+
if (Sse2.IsSupported)
51+
{
52+
Sse2.Store((byte*)dst, Sse2.LoadVector128((byte*)src));
53+
}
54+
else
55+
#endif
56+
{
57+
var v1 = System.Runtime.CompilerServices.Unsafe.ReadUnaligned<ulong>((ulong*)src);
58+
var v2 = System.Runtime.CompilerServices.Unsafe.ReadUnaligned<ulong>((ulong*)src + 1);
59+
System.Runtime.CompilerServices.Unsafe.WriteUnaligned((ulong*)dst, v1);
60+
System.Runtime.CompilerServices.Unsafe.WriteUnaligned((ulong*)dst + 1, v2);
61+
}
3962
}
4063

4164
/*! ZSTD_wildcopy() :

src/ZstdSharp/Unsafe/ZstdLazy.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
using static ZstdSharp.UnsafeHelper;
12
using System.Runtime.CompilerServices;
23
using System.Runtime.Intrinsics;
3-
using static ZstdSharp.UnsafeHelper;
44
#if NETCOREAPP3_0_OR_GREATER
55
using System.Runtime.Intrinsics.X86;
66
#endif

0 commit comments

Comments
 (0)