/// <summary> /// Compute xxHash for the async stream /// </summary> /// <param name="stream">The stream of data</param> /// <param name="bufferSize">The buffer size</param> /// <param name="seed">The seed number</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>The hash</returns> public static async ValueTask <uint> ComputeHashAsync(Stream stream, int bufferSize, uint seed, CancellationToken cancellationToken) { Debug.Assert(stream != null); Debug.Assert(bufferSize > 16); // Optimizing memory allocation byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize + 16); int readBytes; int offset = 0; long length = 0; // Prepare the seed vector uint v1 = seed + p1 + p2; uint v2 = seed + p2; uint v3 = seed + 0; uint v4 = seed - p1; try { // Read flow of bytes while ((readBytes = await stream.ReadAsync(buffer, offset, bufferSize, cancellationToken).ConfigureAwait(false)) > 0) { // Exit if the operation is canceled if (cancellationToken.IsCancellationRequested) { return(await Task.FromCanceled <uint>(cancellationToken)); } length = length + readBytes; offset = offset + readBytes; if (offset < 16) { continue; } int r = offset % 16; // remain int l = offset - r; // length // Process the next chunk UnsafeAlign(buffer, l, ref v1, ref v2, ref v3, ref v4); // Put remaining bytes to buffer UnsafeBuffer.BlockCopy(buffer, l, buffer, 0, r); offset = r; } // Process the final chunk uint h32 = UnsafeFinal(buffer, offset, ref v1, ref v2, ref v3, ref v4, length, seed); return(h32); } finally { // Free memory ArrayPool <byte> .Shared.Return(buffer); } }
/// <summary> /// Compute xxHash for the stream /// </summary> /// <param name="stream">The stream of data</param> /// <param name="bufferSize">The buffer size</param> /// <param name="seed">The seed number</param> /// <returns>The hash</returns> public static ulong ComputeHash(Stream stream, int bufferSize = 8192, ulong seed = 0) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } Debug.Assert(stream != null); Debug.Assert(bufferSize > 32); // Optimizing memory allocation byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize + 32); int readBytes; int offset = 0; long length = 0; // Prepare the seed vector ulong v1 = seed + p1 + p2; ulong v2 = seed + p2; ulong v3 = seed + 0; ulong v4 = seed - p1; try { // Read flow of bytes while ((readBytes = stream.Read(buffer, offset, bufferSize)) > 0) { length += readBytes; offset += readBytes; if (offset < 32) { continue; } int r = offset % 32; // remain int l = offset - r; // length // Process the next chunk UnsafeAlign(buffer, l, ref v1, ref v2, ref v3, ref v4); // Put remaining bytes to buffer UnsafeBuffer.BlockCopy(buffer, l, buffer, 0, r); offset = r; } // Process the final chunk ulong h64 = UnsafeFinal(buffer, offset, ref v1, ref v2, ref v3, ref v4, length, seed); return(h64); } finally { // Free memory ArrayPool <byte> .Shared.Return(buffer); } }
/// <summary> /// Compute xxHash for the stream /// </summary> /// <param name="stream">The stream of data</param> /// <param name="bufferSize">The buffer size</param> /// <param name="seed">The seed number</param> /// <returns>The hash</returns> public static uint ComputeHash(Stream stream, int bufferSize = 4096, uint seed = 0) { Debug.Assert(stream != null); Debug.Assert(bufferSize > 16); // Optimizing memory allocation byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize + 16); int readBytes; int offset = 0; long length = 0; // Prepare the seed vector uint v1 = seed + p1 + p2; uint v2 = seed + p2; uint v3 = seed + 0; uint v4 = seed - p1; try { // Read flow of bytes while ((readBytes = stream.Read(buffer, offset, bufferSize)) > 0) { length = length + readBytes; offset = offset + readBytes; if (offset < 16) { continue; } int r = offset % 16; // remain int l = offset - r; // length // Process the next chunk UnsafeAlign(buffer, l, ref v1, ref v2, ref v3, ref v4); // Put remaining bytes to buffer UnsafeBuffer.BlockCopy(buffer, l, buffer, 0, r); offset = r; } // Process the last chunk uint h32 = UnsafeFinal(buffer, offset, ref v1, ref v2, ref v3, ref v4, length, seed); return(h32); } finally { // Free memory ArrayPool <byte> .Shared.Return(buffer); } }