Added ReadOnlySpan
This commit is contained in:
parent
59d2f824fb
commit
e86fdeb0bf
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# 2018-03-11
|
||||||
|
- Added API for ReadOnlySpan
|
||||||
|
- Added support for the async calls with cancelation tokens
|
||||||
12
README.md
12
README.md
@ -15,7 +15,7 @@
|
|||||||
<img src="https://codecov.io/gh/uranium62/xxHash/branch/master/graph/badge.svg" alt="coverage"/>
|
<img src="https://codecov.io/gh/uranium62/xxHash/branch/master/graph/badge.svg" alt="coverage"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.nuget.org/packages/Standart.Hash.xxHash">
|
<a href="https://www.nuget.org/packages/Standart.Hash.xxHash">
|
||||||
<img src="https://img.shields.io/badge/nuget-1.0.5-green.svg?style=flat-square" alt="nuget"/>
|
<img src="https://img.shields.io/badge/nuget-1.0.6-green.svg?style=flat-square" alt="nuget"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.nuget.org/packages/Standart.Hash.xxHash">
|
<a href="https://www.nuget.org/packages/Standart.Hash.xxHash">
|
||||||
<img src="https://img.shields.io/badge/platform-x64-blue.svg?longCache=true" alt="platform"/>
|
<img src="https://img.shields.io/badge/platform-x64-blue.svg?longCache=true" alt="platform"/>
|
||||||
@ -74,13 +74,15 @@ byte[] data = Encoding.UTF8.GetBytes("veni vidi vici");
|
|||||||
|
|
||||||
ulong h64_1 = xxHash64.ComputeHash(data, data.Length);
|
ulong h64_1 = xxHash64.ComputeHash(data, data.Length);
|
||||||
ulong h64_2 = xxHash64.ComputeHash(new Span<byte>(data), data.Length);
|
ulong h64_2 = xxHash64.ComputeHash(new Span<byte>(data), data.Length);
|
||||||
ulong h64_3 = xxHash64.ComputeHash(new MemoryStream(data));
|
ulong h64_3 = xxHash64.ComputeHash(new ReadOnlySpan<byte>(data), data.Length);
|
||||||
ulong h64_4 = await xxHash64.ComputeHashAsync(new MemoryStream(data));
|
ulong h64_4 = xxHash64.ComputeHash(new MemoryStream(data));
|
||||||
|
ulong h64_5 = await xxHash64.ComputeHashAsync(new MemoryStream(data));
|
||||||
|
|
||||||
uint h32_1 = xxHash32.ComputeHash(data, data.Length);
|
uint h32_1 = xxHash32.ComputeHash(data, data.Length);
|
||||||
uint h32_2 = xxHash32.ComputeHash(new Span<byte>(data), data.Length);
|
uint h32_2 = xxHash32.ComputeHash(new Span<byte>(data), data.Length);
|
||||||
uint h32_3 = xxHash32.ComputeHash(new MemoryStream(data));
|
uint h32_3 = xxHash32.ComputeHash(new ReadOnlySpan<byte>(data), data.Length);
|
||||||
uint h32_4 = await xxHash32.ComputeHashAsync(new MemoryStream(data));
|
uint h32_4 = xxHash32.ComputeHash(new MemoryStream(data));
|
||||||
|
uint h32_5 = await xxHash32.ComputeHashAsync(new MemoryStream(data));
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
||||||
<PackageId>Standart.Hash.xxHash</PackageId>
|
<PackageId>Standart.Hash.xxHash</PackageId>
|
||||||
<VersionPrefix>1.0.5</VersionPrefix>
|
<VersionPrefix>1.0.6</VersionPrefix>
|
||||||
<AssemblyName>Standart.Hash.xxHash</AssemblyName>
|
<AssemblyName>Standart.Hash.xxHash</AssemblyName>
|
||||||
<AssemblyTitle>Standart.Hash.xxHash</AssemblyTitle>
|
<AssemblyTitle>Standart.Hash.xxHash</AssemblyTitle>
|
||||||
<Authors>Alexander Melnik</Authors>
|
<Authors>Alexander Melnik</Authors>
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
[RPlotExporter, RankColumn]
|
[RPlotExporter, RankColumn]
|
||||||
[MinColumn, MaxColumn]
|
[MinColumn, MaxColumn]
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
//[DisassemblyDiagnoser(printAsm: true, printSource: true)]
|
// [DisassemblyDiagnoser(printAsm: true, printSource: true)]
|
||||||
public class xxHashBenchmark
|
public class xxHashBenchmark
|
||||||
{
|
{
|
||||||
const int KB = 1024;
|
const int KB = 1024;
|
||||||
@ -44,6 +44,13 @@
|
|||||||
return xxHash32.ComputeHash(span, span.Length);
|
return xxHash32.ComputeHash(span, span.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public uint Hash32_ReadOnlySpan()
|
||||||
|
{
|
||||||
|
ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(data);
|
||||||
|
return xxHash32.ComputeHash(span, span.Length);
|
||||||
|
}
|
||||||
|
|
||||||
[Benchmark]
|
[Benchmark]
|
||||||
public uint Hash32_Stream()
|
public uint Hash32_Stream()
|
||||||
{
|
{
|
||||||
@ -71,6 +78,13 @@
|
|||||||
return xxHash64.ComputeHash(span, span.Length);
|
return xxHash64.ComputeHash(span, span.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public ulong Hash64_ReadOnlySpan()
|
||||||
|
{
|
||||||
|
ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(data);
|
||||||
|
return xxHash64.ComputeHash(span, span.Length);
|
||||||
|
}
|
||||||
|
|
||||||
[Benchmark]
|
[Benchmark]
|
||||||
public ulong Hash64_Stream()
|
public ulong Hash64_Stream()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -13,14 +14,17 @@
|
|||||||
// Arrange
|
// Arrange
|
||||||
byte[] data = {0xde};
|
byte[] data = {0xde};
|
||||||
Span<byte> span = new Span<byte>(data);
|
Span<byte> span = new Span<byte>(data);
|
||||||
|
ReadOnlySpan<byte> rspan = new ReadOnlySpan<byte>(data);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
||||||
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
||||||
|
uint hash3 = xxHash32.ComputeHash(rspan, rspan.Length);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(hash1, (uint) 0x2330eac0);
|
Assert.Equal(hash1, (uint) 0x2330eac0);
|
||||||
Assert.Equal(hash2, (uint) 0x2330eac0);
|
Assert.Equal(hash2, (uint) 0x2330eac0);
|
||||||
|
Assert.Equal(hash3, (uint) 0x2330eac0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -29,14 +33,17 @@
|
|||||||
// Arrange
|
// Arrange
|
||||||
byte[] data = {0xde, 0x55, 0x47, 0x7f, 0x14};
|
byte[] data = {0xde, 0x55, 0x47, 0x7f, 0x14};
|
||||||
Span<byte> span = new Span<byte>(data);
|
Span<byte> span = new Span<byte>(data);
|
||||||
|
ReadOnlySpan<byte> rspan = new ReadOnlySpan<byte>(data);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
||||||
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
||||||
|
uint hash3 = xxHash32.ComputeHash(rspan, rspan.Length);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(hash1, (uint) 0x112348ba);
|
Assert.Equal(hash1, (uint) 0x112348ba);
|
||||||
Assert.Equal(hash2, (uint) 0x112348ba);
|
Assert.Equal(hash2, (uint) 0x112348ba);
|
||||||
|
Assert.Equal(hash3, (uint) 0x112348ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -49,14 +56,17 @@
|
|||||||
0x22, 0x3a, 0x40, 0x96, 0x56, 0xc5, 0xdc, 0xbb
|
0x22, 0x3a, 0x40, 0x96, 0x56, 0xc5, 0xdc, 0xbb
|
||||||
};
|
};
|
||||||
Span<byte> span = new Span<byte>(data);
|
Span<byte> span = new Span<byte>(data);
|
||||||
|
ReadOnlySpan<byte> rspan = new ReadOnlySpan<byte>(data);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
||||||
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
||||||
|
uint hash3 = xxHash32.ComputeHash(rspan, rspan.Length);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(hash1, (uint) 0xcdf89609);
|
Assert.Equal(hash1, (uint) 0xcdf89609);
|
||||||
Assert.Equal(hash2, (uint) 0xcdf89609);
|
Assert.Equal(hash2, (uint) 0xcdf89609);
|
||||||
|
Assert.Equal(hash3, (uint) 0xcdf89609);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -70,14 +80,17 @@
|
|||||||
0x0e
|
0x0e
|
||||||
};
|
};
|
||||||
Span<byte> span = new Span<byte>(data);
|
Span<byte> span = new Span<byte>(data);
|
||||||
|
ReadOnlySpan<byte> rspan = new ReadOnlySpan<byte>(data);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
||||||
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
||||||
|
uint hash3 = xxHash32.ComputeHash(rspan, rspan.Length);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(hash1, (uint) 0xbca8f924);
|
Assert.Equal(hash1, (uint) 0xbca8f924);
|
||||||
Assert.Equal(hash2, (uint) 0xbca8f924);
|
Assert.Equal(hash2, (uint) 0xbca8f924);
|
||||||
|
Assert.Equal(hash3, (uint) 0xbca8f924);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -91,14 +104,17 @@
|
|||||||
0x0e, 0x59, 0x4d, 0x42, 0xc5
|
0x0e, 0x59, 0x4d, 0x42, 0xc5
|
||||||
};
|
};
|
||||||
Span<byte> span = new Span<byte>(data);
|
Span<byte> span = new Span<byte>(data);
|
||||||
|
ReadOnlySpan<byte> rspan = new ReadOnlySpan<byte>(data);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
||||||
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
||||||
|
uint hash3 = xxHash32.ComputeHash(rspan, rspan.Length);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(hash1, (uint) 0xf4518e14);
|
Assert.Equal(hash1, (uint) 0xf4518e14);
|
||||||
Assert.Equal(hash2, (uint) 0xf4518e14);
|
Assert.Equal(hash2, (uint) 0xf4518e14);
|
||||||
|
Assert.Equal(hash3, (uint) 0xf4518e14);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -113,14 +129,17 @@
|
|||||||
0x1c, 0x2c, 0xc9, 0x38, 0x7d, 0x43, 0x83, 0x11,
|
0x1c, 0x2c, 0xc9, 0x38, 0x7d, 0x43, 0x83, 0x11,
|
||||||
};
|
};
|
||||||
Span<byte> span = new Span<byte>(data);
|
Span<byte> span = new Span<byte>(data);
|
||||||
|
ReadOnlySpan<byte> rspan = new ReadOnlySpan<byte>(data);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
uint hash1 = xxHash32.ComputeHash(data, data.Length);
|
||||||
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
uint hash2 = xxHash32.ComputeHash(span, span.Length);
|
||||||
|
uint hash3 = xxHash32.ComputeHash(rspan, rspan.Length);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(hash1, (uint) 0xf8497daa);
|
Assert.Equal(hash1, (uint) 0xf8497daa);
|
||||||
Assert.Equal(hash2, (uint) 0xf8497daa);
|
Assert.Equal(hash2, (uint) 0xf8497daa);
|
||||||
|
Assert.Equal(hash3, (uint) 0xf8497daa);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -349,6 +368,29 @@
|
|||||||
Assert.Equal(hash, (uint) 0xf8497daa);
|
Assert.Equal(hash, (uint) 0xf8497daa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Compute_hash32_for_the_async_stream_32_with_cancelation_token()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
byte[] data = new byte[]
|
||||||
|
{
|
||||||
|
0xde, 0x55, 0x47, 0x7f, 0x14, 0x8f, 0xf1, 0x48,
|
||||||
|
0x22, 0x3a, 0x40, 0x96, 0x56, 0xc5, 0xdc, 0xbb,
|
||||||
|
0x0e, 0x59, 0x4d, 0x42, 0xc5, 0x07, 0x21, 0x08,
|
||||||
|
0x1c, 0x2c, 0xc9, 0x38, 0x7d, 0x43, 0x83, 0x11,
|
||||||
|
};
|
||||||
|
CancellationTokenSource tokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
tokenSource.Cancel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await Assert.ThrowsAsync<TaskCanceledException>(async () =>
|
||||||
|
{
|
||||||
|
await xxHash32.ComputeHashAsync(new MemoryStream(data), 4096, 0, tokenSource.Token);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Compute_hash32_for_the_async_random_stream()
|
public async Task Compute_hash32_for_the_async_random_stream()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -13,14 +14,17 @@
|
|||||||
// Arrange
|
// Arrange
|
||||||
byte[] data = {0x60};
|
byte[] data = {0x60};
|
||||||
Span<byte> span = new Span<byte>(data);
|
Span<byte> span = new Span<byte>(data);
|
||||||
|
ReadOnlySpan<byte> rspan = new ReadOnlySpan<byte>(data);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ulong hash1 = xxHash64.ComputeHash(data, data.Length);
|
ulong hash1 = xxHash64.ComputeHash(data, data.Length);
|
||||||
ulong hash2 = xxHash64.ComputeHash(span, data.Length);
|
ulong hash2 = xxHash64.ComputeHash(span, span.Length);
|
||||||
|
ulong hash3 = xxHash64.ComputeHash(rspan, rspan.Length);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(hash1, (ulong) 0xb3e7ca6ca5ba3445);
|
Assert.Equal(hash1, (ulong) 0xb3e7ca6ca5ba3445);
|
||||||
Assert.Equal(hash2, (ulong) 0xb3e7ca6ca5ba3445);
|
Assert.Equal(hash2, (ulong) 0xb3e7ca6ca5ba3445);
|
||||||
|
Assert.Equal(hash3, (ulong) 0xb3e7ca6ca5ba3445);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -29,14 +33,17 @@
|
|||||||
// Arrange
|
// Arrange
|
||||||
byte[] data = {0x60, 0x82, 0x40, 0x77, 0x8a};
|
byte[] data = {0x60, 0x82, 0x40, 0x77, 0x8a};
|
||||||
Span<byte> span = new Span<byte>(data);
|
Span<byte> span = new Span<byte>(data);
|
||||||
|
ReadOnlySpan<byte> rspan = new ReadOnlySpan<byte>(data);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ulong hash1 = xxHash64.ComputeHash(data, data.Length);
|
ulong hash1 = xxHash64.ComputeHash(data, data.Length);
|
||||||
ulong hash2 = xxHash64.ComputeHash(span, data.Length);
|
ulong hash2 = xxHash64.ComputeHash(span, span.Length);
|
||||||
|
ulong hash3 = xxHash64.ComputeHash(rspan, rspan.Length);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(hash1, (ulong) 0x917b11ed024938fc);
|
Assert.Equal(hash1, (ulong) 0x917b11ed024938fc);
|
||||||
Assert.Equal(hash2, (ulong) 0x917b11ed024938fc);
|
Assert.Equal(hash2, (ulong) 0x917b11ed024938fc);
|
||||||
|
Assert.Equal(hash3, (ulong) 0x917b11ed024938fc);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -49,14 +56,17 @@
|
|||||||
0x85, 0x1f, 0xa6, 0x86, 0x34,
|
0x85, 0x1f, 0xa6, 0x86, 0x34,
|
||||||
};
|
};
|
||||||
Span<byte> span = new Span<byte>(data);
|
Span<byte> span = new Span<byte>(data);
|
||||||
|
ReadOnlySpan<byte> rspan = new ReadOnlySpan<byte>(data);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ulong hash1 = xxHash64.ComputeHash(data, data.Length);
|
ulong hash1 = xxHash64.ComputeHash(data, data.Length);
|
||||||
ulong hash2 = xxHash64.ComputeHash(span, data.Length);
|
ulong hash2 = xxHash64.ComputeHash(span, span.Length);
|
||||||
|
ulong hash3 = xxHash64.ComputeHash(rspan, rspan.Length);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(hash1, (ulong) 0x9d1cb0d181d58bee);
|
Assert.Equal(hash1, (ulong) 0x9d1cb0d181d58bee);
|
||||||
Assert.Equal(hash2, (ulong) 0x9d1cb0d181d58bee);
|
Assert.Equal(hash2, (ulong) 0x9d1cb0d181d58bee);
|
||||||
|
Assert.Equal(hash3, (ulong) 0x9d1cb0d181d58bee);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -71,14 +81,17 @@
|
|||||||
0x4b, 0x0f, 0x90, 0x4e, 0xf5, 0x57, 0x21, 0x21,
|
0x4b, 0x0f, 0x90, 0x4e, 0xf5, 0x57, 0x21, 0x21,
|
||||||
};
|
};
|
||||||
Span<byte> span = new Span<byte>(data);
|
Span<byte> span = new Span<byte>(data);
|
||||||
|
ReadOnlySpan<byte> rspan = new ReadOnlySpan<byte>(data);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ulong hash1 = xxHash64.ComputeHash(data, data.Length);
|
ulong hash1 = xxHash64.ComputeHash(data, data.Length);
|
||||||
ulong hash2 = xxHash64.ComputeHash(span, data.Length);
|
ulong hash2 = xxHash64.ComputeHash(span, span.Length);
|
||||||
|
ulong hash3 = xxHash64.ComputeHash(rspan, rspan.Length);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(hash1, (ulong) 0x9233096b7804e12c);
|
Assert.Equal(hash1, (ulong) 0x9233096b7804e12c);
|
||||||
Assert.Equal(hash2, (ulong) 0x9233096b7804e12c);
|
Assert.Equal(hash2, (ulong) 0x9233096b7804e12c);
|
||||||
|
Assert.Equal(hash3, (ulong) 0x9233096b7804e12c);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -97,14 +110,17 @@
|
|||||||
0x7e, 0x28, 0xce, 0x46, 0x85, 0xb7, 0x2b, 0x16,
|
0x7e, 0x28, 0xce, 0x46, 0x85, 0xb7, 0x2b, 0x16,
|
||||||
};
|
};
|
||||||
Span<byte> span = new Span<byte>(data);
|
Span<byte> span = new Span<byte>(data);
|
||||||
|
ReadOnlySpan<byte> rspan = new ReadOnlySpan<byte>(data);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ulong hash1 = xxHash64.ComputeHash(data, data.Length);
|
ulong hash1 = xxHash64.ComputeHash(data, data.Length);
|
||||||
ulong hash2 = xxHash64.ComputeHash(span, data.Length);
|
ulong hash2 = xxHash64.ComputeHash(span, span.Length);
|
||||||
|
ulong hash3 = xxHash64.ComputeHash(rspan, rspan.Length);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(hash1, (ulong) 0x4c0a65b1ef9ea060);
|
Assert.Equal(hash1, (ulong) 0x4c0a65b1ef9ea060);
|
||||||
Assert.Equal(hash2, (ulong) 0x4c0a65b1ef9ea060);
|
Assert.Equal(hash2, (ulong) 0x4c0a65b1ef9ea060);
|
||||||
|
Assert.Equal(hash3, (ulong) 0x4c0a65b1ef9ea060);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -192,6 +208,7 @@
|
|||||||
Assert.Equal(hash, (ulong) 0x4c0a65b1ef9ea060);
|
Assert.Equal(hash, (ulong) 0x4c0a65b1ef9ea060);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Compute_hash64_for_the_random_stream()
|
public void Compute_hash64_for_the_random_stream()
|
||||||
{
|
{
|
||||||
@ -308,6 +325,33 @@
|
|||||||
Assert.Equal(hash, (ulong) 0x4c0a65b1ef9ea060);
|
Assert.Equal(hash, (ulong) 0x4c0a65b1ef9ea060);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Compute_hash64_for_the_async_stream_64_with_cancelation_token()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
byte[] data =
|
||||||
|
{
|
||||||
|
0x60, 0x82, 0x40, 0x77, 0x8a, 0x0e, 0xe4, 0xd5,
|
||||||
|
0x85, 0x1f, 0xa6, 0x86, 0x34, 0x01, 0xd7, 0xf2,
|
||||||
|
0x30, 0x5d, 0x84, 0x54, 0x15, 0xf9, 0xbd, 0x03,
|
||||||
|
0x4b, 0x0f, 0x90, 0x4e, 0xf5, 0x57, 0x21, 0x21,
|
||||||
|
0xed, 0x8c, 0x19, 0x93, 0xbd, 0x01, 0x12, 0x0c,
|
||||||
|
0x20, 0xb0, 0x33, 0x98, 0x4b, 0xe7, 0xc1, 0x0a,
|
||||||
|
0x27, 0x6d, 0xb3, 0x5c, 0xc7, 0xc0, 0xd0, 0xa0,
|
||||||
|
0x7e, 0x28, 0xce, 0x46, 0x85, 0xb7, 0x2b, 0x16,
|
||||||
|
};
|
||||||
|
CancellationTokenSource tokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
tokenSource.Cancel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await Assert.ThrowsAsync<TaskCanceledException>(async() =>
|
||||||
|
{
|
||||||
|
await xxHash64.ComputeHashAsync(new MemoryStream(data), 8192, 0, tokenSource.Token);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Compute_hash64_for_the_async_random_stream()
|
public async Task Compute_hash64_for_the_async_random_stream()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public static partial class xxHash32
|
public static partial class xxHash32
|
||||||
@ -15,6 +16,20 @@
|
|||||||
/// <param name="seed">The seed number</param>
|
/// <param name="seed">The seed number</param>
|
||||||
/// <returns>The hash</returns>
|
/// <returns>The hash</returns>
|
||||||
public static async ValueTask<uint> ComputeHashAsync(Stream stream, int bufferSize = 4096, uint seed = 0)
|
public static async ValueTask<uint> ComputeHashAsync(Stream stream, int bufferSize = 4096, uint seed = 0)
|
||||||
|
{
|
||||||
|
return await ComputeHashAsync(stream, bufferSize, seed, CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <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(stream != null);
|
||||||
Debug.Assert(bufferSize > 16);
|
Debug.Assert(bufferSize > 16);
|
||||||
@ -35,8 +50,14 @@
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Read flow of bytes
|
// Read flow of bytes
|
||||||
while ((readBytes = await stream.ReadAsync(buffer, offset, bufferSize).ConfigureAwait(false)) > 0)
|
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;
|
length = length + readBytes;
|
||||||
offset = offset + readBytes;
|
offset = offset + readBytes;
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,8 @@ using System.Diagnostics;
|
|||||||
|
|
||||||
namespace Standart.Hash.xxHash
|
namespace Standart.Hash.xxHash
|
||||||
{
|
{
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
public static partial class xxHash32
|
public static partial class xxHash32
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -18,7 +20,26 @@ namespace Standart.Hash.xxHash
|
|||||||
Debug.Assert(length >= 0);
|
Debug.Assert(length >= 0);
|
||||||
Debug.Assert(length <= data.Length);
|
Debug.Assert(length <= data.Length);
|
||||||
|
|
||||||
fixed (byte* pData = &data[0])
|
fixed (byte* pData = &MemoryMarshal.GetReference(data))
|
||||||
|
{
|
||||||
|
return UnsafeComputeHash(pData, length, seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compute xxHash for the data byte span
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">The source of data</param>
|
||||||
|
/// <param name="length">The length of the data for hashing</param>
|
||||||
|
/// <param name="seed">The seed number</param>
|
||||||
|
/// <returns>hash</returns>
|
||||||
|
public static unsafe uint ComputeHash(ReadOnlySpan<byte> data, int length, uint seed = 0)
|
||||||
|
{
|
||||||
|
Debug.Assert(data != null);
|
||||||
|
Debug.Assert(length >= 0);
|
||||||
|
Debug.Assert(length <= data.Length);
|
||||||
|
|
||||||
|
fixed (byte* pData = &MemoryMarshal.GetReference(data))
|
||||||
{
|
{
|
||||||
return UnsafeComputeHash(pData, length, seed);
|
return UnsafeComputeHash(pData, length, seed);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public static partial class xxHash64
|
public static partial class xxHash64
|
||||||
@ -15,6 +16,19 @@
|
|||||||
/// <param name="seed">The seed number</param>
|
/// <param name="seed">The seed number</param>
|
||||||
/// <returns>The hash</returns>
|
/// <returns>The hash</returns>
|
||||||
public static async ValueTask<ulong> ComputeHashAsync(Stream stream, int bufferSize = 8192, ulong seed = 0)
|
public static async ValueTask<ulong> ComputeHashAsync(Stream stream, int bufferSize = 8192, ulong seed = 0)
|
||||||
|
{
|
||||||
|
return await ComputeHashAsync(stream, bufferSize, seed, CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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 cancelation token</param>
|
||||||
|
/// <returns>The hash</returns>
|
||||||
|
public static async ValueTask<ulong> ComputeHashAsync(Stream stream, int bufferSize, ulong seed, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Debug.Assert(stream != null);
|
Debug.Assert(stream != null);
|
||||||
Debug.Assert(bufferSize > 32);
|
Debug.Assert(bufferSize > 32);
|
||||||
@ -35,8 +49,14 @@
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Read flow of bytes
|
// Read flow of bytes
|
||||||
while ((readBytes = await stream.ReadAsync(buffer, offset, bufferSize).ConfigureAwait(false)) > 0)
|
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<ulong>(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
length = length + readBytes;
|
length = length + readBytes;
|
||||||
offset = offset + readBytes;
|
offset = offset + readBytes;
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
public static partial class xxHash64
|
public static partial class xxHash64
|
||||||
{
|
{
|
||||||
@ -18,7 +19,26 @@
|
|||||||
Debug.Assert(length >= 0);
|
Debug.Assert(length >= 0);
|
||||||
Debug.Assert(length <= data.Length);
|
Debug.Assert(length <= data.Length);
|
||||||
|
|
||||||
fixed (byte* pData = &data[0])
|
fixed (byte* pData = &MemoryMarshal.GetReference(data))
|
||||||
|
{
|
||||||
|
return UnsafeComputeHash(pData, length, seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compute xxHash for the data byte span
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">The source of data</param>
|
||||||
|
/// <param name="length">The length of the data for hashing</param>
|
||||||
|
/// <param name="seed">The seed number</param>
|
||||||
|
/// <returns>hash</returns>
|
||||||
|
public static unsafe ulong ComputeHash(ReadOnlySpan<byte> data, int length, ulong seed = 0)
|
||||||
|
{
|
||||||
|
Debug.Assert(data != null);
|
||||||
|
Debug.Assert(length >= 0);
|
||||||
|
Debug.Assert(length <= data.Length);
|
||||||
|
|
||||||
|
fixed (byte* pData = &MemoryMarshal.GetReference(data))
|
||||||
{
|
{
|
||||||
return UnsafeComputeHash(pData, length, seed);
|
return UnsafeComputeHash(pData, length, seed);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user