Data.HashFunction 3.1.1
DHF
Loading...
Searching...
No Matches
Data.HashFunction.Blake3.Hasher Class Reference

An incremental hash state that can accept any number of writes. More...

+ Inheritance diagram for Data.HashFunction.Blake3.Hasher:
+ Collaboration diagram for Data.HashFunction.Blake3.Hasher:

Public Member Functions

void Dispose ()
 Dispose this instance.
 
void Reset ()
 Reset the Hasher to its initial state.
 
void Update (ReadOnlySpan< byte > data)
 Add input bytes to the hash state. You can call this any number of times.
 
void Update< T > (ReadOnlySpan< T > data)
 Add input data to the hash state. You can call this any number of times.
 
void UpdateWithJoin (ReadOnlySpan< byte > data)
 Add input bytes to the hash state, as with update, but potentially using multi-threading.
 
void UpdateWithJoin< T > (ReadOnlySpan< T > data)
 Add input data span to the hash state, as with update, but potentially using multi-threading.
 
void Finalize (Span< byte > hash)
 Finalize the hash state to the output span, which can supply any number of output bytes.
 
void Finalize (ulong offset, Span< byte > hash)
 Finalize the hash state to the output span, which can supply any number of output bytes.
 
void Finalize (long offset, Span< byte > hash)
 Finalize the hash state to the output span, which can supply any number of output bytes.
 

Static Public Member Functions

static void Hash (ReadOnlySpan< byte > input, Span< byte > output)
 The default hash function.
 
static Hasher New ()
 Construct a new Hasher for the regular hash function.
 
static Hasher NewKeyed (ReadOnlySpan< byte > key)
 Construct a new Hasher for the keyed hash function.
 
static Hasher NewDeriveKey (string text)
 Construct a new Hasher for the key derivation function.
 
static Hasher NewDeriveKey (ReadOnlySpan< byte > str)
 Construct a new Hasher for the key derivation function.
 

Private Member Functions

delegate void * blake3_new_del ()
 
delegate void * blake3_new_keyed_del (void *ptr32Bytes)
 
delegate void * blake3_new_derive_key_del (void *ptr, void *size)
 
delegate void blake3_hash_del (void *ptr, void *size, void *ptrOut)
 
delegate void blake3_hash_preemptive_del (void *ptr, void *size, void *ptrOut)
 
delegate void blake3_delete_del (void *hasher)
 
delegate void blake3_reset_del (void *hasher)
 
delegate void blake3_update_del (void *hasher, void *ptr, void *size)
 
delegate void blake3_update_preemptive_del (void *hasher, void *ptr, void *size)
 
delegate void blake3_update_rayon_del (void *hasher, void *ptr, void *size)
 
delegate void blake3_finalize_del (void *hasher, void *ptr)
 
delegate void blake3_finalize_xof_del (void *hasher, void *ptr, void *size)
 
delegate void blake3_finalize_seek_xof_del (void *hasher, ulong offset, void *ptr, void *size)
 
 Hasher (void *hasher)
 

Static Private Member Functions

static Hasher ()
 
static void FastUpdate (void *hasher, void *ptr, long size)
 
static void ThrowNullReferenceException ()
 
static void ThrowArgumentNullException ()
 
static void ThrowArgumentOutOfRange (int size)
 

Private Attributes

void * _hasher
 

Static Private Attributes

static readonly blake3_new_del blake3_new
 
static readonly blake3_new_keyed_del blake3_new_keyed
 
static readonly blake3_new_derive_key_del blake3_new_derive_key
 
static readonly blake3_hash_del blake3_hash
 
static readonly blake3_hash_preemptive_del blake3_hash_preemptive
 
static readonly blake3_delete_del blake3_delete
 
static readonly blake3_reset_del blake3_reset
 
static readonly blake3_update_del blake3_update
 
static readonly blake3_update_preemptive_del blake3_update_preemptive
 
static readonly blake3_update_rayon_del blake3_update_rayon
 
static readonly blake3_finalize_del blake3_finalize
 
static readonly blake3_finalize_xof_del blake3_finalize_xof
 
static readonly blake3_finalize_seek_xof_del blake3_finalize_seek_xof
 
static NativeLibraryLoader lib_loader
 
const int LimitPreemptive = 1024
 We are taking a limit of 1024 bytes to switch to a preemptive version, as it takes around 1μs on a x64 very recent CPU to complete, which is better aligned with the documentation of SuppressGCTransitionAttribute: Native function always executes for a trivial amount of time (less than 1 microsecond).
 

Detailed Description

An incremental hash state that can accept any number of writes.

Performance note: The Update<T> and UpdateWithJoin<T> methods perform poorly when the caller's input buffer is small. See their method docs below. A 16 KiB buffer is large enough to leverage all currently supported SIMD instruction sets.

Constructor & Destructor Documentation

◆ Hasher() [1/2]

static Data.HashFunction.Blake3.Hasher.Hasher ( )
staticprivate
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Hasher() [2/2]

Data.HashFunction.Blake3.Hasher.Hasher ( void * hasher)
private

Member Function Documentation

◆ blake3_delete_del()

delegate void Data.HashFunction.Blake3.Hasher.blake3_delete_del ( void * hasher)
private
+ Here is the caller graph for this function:

◆ blake3_finalize_del()

delegate void Data.HashFunction.Blake3.Hasher.blake3_finalize_del ( void * hasher,
void * ptr )
private
+ Here is the caller graph for this function:

◆ blake3_finalize_seek_xof_del()

delegate void Data.HashFunction.Blake3.Hasher.blake3_finalize_seek_xof_del ( void * hasher,
ulong offset,
void * ptr,
void * size )
private
+ Here is the caller graph for this function:

◆ blake3_finalize_xof_del()

delegate void Data.HashFunction.Blake3.Hasher.blake3_finalize_xof_del ( void * hasher,
void * ptr,
void * size )
private
+ Here is the caller graph for this function:

◆ blake3_hash_del()

delegate void Data.HashFunction.Blake3.Hasher.blake3_hash_del ( void * ptr,
void * size,
void * ptrOut )
private
+ Here is the caller graph for this function:

◆ blake3_hash_preemptive_del()

delegate void Data.HashFunction.Blake3.Hasher.blake3_hash_preemptive_del ( void * ptr,
void * size,
void * ptrOut )
private
+ Here is the caller graph for this function:

◆ blake3_new_del()

delegate void * Data.HashFunction.Blake3.Hasher.blake3_new_del ( )
private
+ Here is the caller graph for this function:

◆ blake3_new_derive_key_del()

delegate void * Data.HashFunction.Blake3.Hasher.blake3_new_derive_key_del ( void * ptr,
void * size )
private
+ Here is the caller graph for this function:

◆ blake3_new_keyed_del()

delegate void * Data.HashFunction.Blake3.Hasher.blake3_new_keyed_del ( void * ptr32Bytes)
private
+ Here is the caller graph for this function:

◆ blake3_reset_del()

delegate void Data.HashFunction.Blake3.Hasher.blake3_reset_del ( void * hasher)
private
+ Here is the caller graph for this function:

◆ blake3_update_del()

delegate void Data.HashFunction.Blake3.Hasher.blake3_update_del ( void * hasher,
void * ptr,
void * size )
private
+ Here is the caller graph for this function:

◆ blake3_update_preemptive_del()

delegate void Data.HashFunction.Blake3.Hasher.blake3_update_preemptive_del ( void * hasher,
void * ptr,
void * size )
private
+ Here is the caller graph for this function:

◆ blake3_update_rayon_del()

delegate void Data.HashFunction.Blake3.Hasher.blake3_update_rayon_del ( void * hasher,
void * ptr,
void * size )
private
+ Here is the caller graph for this function:

◆ Dispose()

void Data.HashFunction.Blake3.Hasher.Dispose ( )

Dispose this instance.

◆ FastUpdate()

static void Data.HashFunction.Blake3.Hasher.FastUpdate ( void * hasher,
void * ptr,
long size )
staticprivate
+ Here is the caller graph for this function:

◆ Finalize() [1/3]

void Data.HashFunction.Blake3.Hasher.Finalize ( long offset,
Span< byte > hash )

Finalize the hash state to the output span, which can supply any number of output bytes.

Parameters
offsetThe offset to seek to in the output stream, relative to the start.
hashThe output hash, which can supply any number of output bytes.

This method is idempotent. Calling it twice will give the same result. You can also add more input and finalize again.

+ Here is the call graph for this function:

◆ Finalize() [2/3]

void Data.HashFunction.Blake3.Hasher.Finalize ( Span< byte > hash)

Finalize the hash state to the output span, which can supply any number of output bytes.

Parameters
hashThe output hash, which can supply any number of output bytes.

This method is idempotent. Calling it twice will give the same result. You can also add more input and finalize again.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Finalize() [3/3]

void Data.HashFunction.Blake3.Hasher.Finalize ( ulong offset,
Span< byte > hash )

Finalize the hash state to the output span, which can supply any number of output bytes.

Parameters
offsetThe offset to seek to in the output stream, relative to the start.
hashThe output hash, which can supply any number of output bytes.

This method is idempotent. Calling it twice will give the same result. You can also add more input and finalize again.

+ Here is the call graph for this function:

◆ Hash()

static void Data.HashFunction.Blake3.Hasher.Hash ( ReadOnlySpan< byte > input,
Span< byte > output )
static

The default hash function.

Parameters
inputThe input data to hash.
outputThe output hash.

For an incremental version that accepts multiple writes Update<T> This function is always single-threaded. For multi-threading support UpdateWithJoin

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ New()

static Hasher Data.HashFunction.Blake3.Hasher.New ( )
static

Construct a new Hasher for the regular hash function.

Returns
A new instance of the hasher

The struct returned needs to be disposed explicitly.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ NewDeriveKey() [1/2]

static Hasher Data.HashFunction.Blake3.Hasher.NewDeriveKey ( ReadOnlySpan< byte > str)
static

Construct a new Hasher for the key derivation function.

Returns
A new instance of the hasher

The struct returned needs to be disposed explicitly.

+ Here is the call graph for this function:

◆ NewDeriveKey() [2/2]

static Hasher Data.HashFunction.Blake3.Hasher.NewDeriveKey ( string text)
static

Construct a new Hasher for the key derivation function.

Returns
A new instance of the hasher

The struct returned needs to be disposed explicitly.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ NewKeyed()

static Hasher Data.HashFunction.Blake3.Hasher.NewKeyed ( ReadOnlySpan< byte > key)
static

Construct a new Hasher for the keyed hash function.

Parameters
keyA 32 byte key.
Returns
A new instance of the hasher

The struct returned needs to be disposed explicitly.

+ Here is the call graph for this function:

◆ Reset()

void Data.HashFunction.Blake3.Hasher.Reset ( )

Reset the Hasher to its initial state.

This is functionally the same as overwriting the Hasher with a new one, using the same key or context string if any. However, depending on how much inlining the optimizer does, moving a Hasher might copy its entire CV stack, most of which is useless uninitialized bytes. This methods avoids that copy.

+ Here is the call graph for this function:

◆ ThrowArgumentNullException()

static void Data.HashFunction.Blake3.Hasher.ThrowArgumentNullException ( )
staticprivate
+ Here is the caller graph for this function:

◆ ThrowArgumentOutOfRange()

static void Data.HashFunction.Blake3.Hasher.ThrowArgumentOutOfRange ( int size)
staticprivate

◆ ThrowNullReferenceException()

static void Data.HashFunction.Blake3.Hasher.ThrowNullReferenceException ( )
staticprivate
+ Here is the caller graph for this function:

◆ Update()

void Data.HashFunction.Blake3.Hasher.Update ( ReadOnlySpan< byte > data)

Add input bytes to the hash state. You can call this any number of times.

Parameters
dataThe input data byte buffer to hash.

This method is always single-threaded. For multi-threading support, see UpdateWithJoin below.

Note that the degree of SIMD parallelism that update can use is limited by the size of this input buffer. The 8 KiB buffer currently used by std::io::copy is enough to leverage AVX2, for example, but not enough to leverage AVX-512. A 16 KiB buffer is large enough to leverage all currently supported SIMD instruction sets.

+ Here is the call graph for this function:

◆ Update< T >()

void Data.HashFunction.Blake3.Hasher.Update< T > ( ReadOnlySpan< T > data)

Add input data to the hash state. You can call this any number of times.

Template Parameters
TType of the data
Parameters
dataThe data span to hash.

This method is always single-threaded. For multi-threading support, see UpdateWithJoin below.

Note that the degree of SIMD parallelism that update can use is limited by the size of this input buffer. The 8 KiB buffer currently used by std::io::copy is enough to leverage AVX2, for example, but not enough to leverage AVX-512. A 16 KiB buffer is large enough to leverage all currently supported SIMD instruction sets.

Type Constraints
T :unmanaged 
+ Here is the call graph for this function:

◆ UpdateWithJoin()

void Data.HashFunction.Blake3.Hasher.UpdateWithJoin ( ReadOnlySpan< byte > data)

Add input bytes to the hash state, as with update, but potentially using multi-threading.

Parameters
dataThe input byte buffer.

To get any performance benefit from multi-threading, the input buffer size needs to be very large. As a rule of thumb on x86_64, there is no benefit to multi-threading inputs less than 128 KiB. Other platforms have different thresholds, and in general you need to benchmark your specific use case. Where possible, memory mapping an entire input file is recommended, to take maximum advantage of multi-threading without needing to tune a specific buffer size. Where memory mapping is not possible, good multi-threading performance requires doing IO on a background thread, to avoid sleeping all your worker threads while the input buffer is (serially) refilled. This is quite complicated compared to memory mapping.

+ Here is the call graph for this function:

◆ UpdateWithJoin< T >()

void Data.HashFunction.Blake3.Hasher.UpdateWithJoin< T > ( ReadOnlySpan< T > data)

Add input data span to the hash state, as with update, but potentially using multi-threading.

Parameters
dataThe input data buffer.

To get any performance benefit from multi-threading, the input buffer size needs to be very large. As a rule of thumb on x86_64, there is no benefit to multi-threading inputs less than 128 KiB. Other platforms have different thresholds, and in general you need to benchmark your specific use case. Where possible, memory mapping an entire input file is recommended, to take maximum advantage of multi-threading without needing to tune a specific buffer size. Where memory mapping is not possible, good multi-threading performance requires doing IO on a background thread, to avoid sleeping all your worker threads while the input buffer is (serially) refilled. This is quite complicated compared to memory mapping.

Type Constraints
T :unmanaged 
+ Here is the call graph for this function:

Member Data Documentation

◆ _hasher

void* Data.HashFunction.Blake3.Hasher._hasher
private

◆ blake3_delete

readonly blake3_delete_del Data.HashFunction.Blake3.Hasher.blake3_delete
staticprivate

◆ blake3_finalize

readonly blake3_finalize_del Data.HashFunction.Blake3.Hasher.blake3_finalize
staticprivate

◆ blake3_finalize_seek_xof

readonly blake3_finalize_seek_xof_del Data.HashFunction.Blake3.Hasher.blake3_finalize_seek_xof
staticprivate

◆ blake3_finalize_xof

readonly blake3_finalize_xof_del Data.HashFunction.Blake3.Hasher.blake3_finalize_xof
staticprivate

◆ blake3_hash

readonly blake3_hash_del Data.HashFunction.Blake3.Hasher.blake3_hash
staticprivate

◆ blake3_hash_preemptive

readonly blake3_hash_preemptive_del Data.HashFunction.Blake3.Hasher.blake3_hash_preemptive
staticprivate

◆ blake3_new

readonly blake3_new_del Data.HashFunction.Blake3.Hasher.blake3_new
staticprivate

◆ blake3_new_derive_key

readonly blake3_new_derive_key_del Data.HashFunction.Blake3.Hasher.blake3_new_derive_key
staticprivate

◆ blake3_new_keyed

readonly blake3_new_keyed_del Data.HashFunction.Blake3.Hasher.blake3_new_keyed
staticprivate

◆ blake3_reset

readonly blake3_reset_del Data.HashFunction.Blake3.Hasher.blake3_reset
staticprivate

◆ blake3_update

readonly blake3_update_del Data.HashFunction.Blake3.Hasher.blake3_update
staticprivate

◆ blake3_update_preemptive

readonly blake3_update_preemptive_del Data.HashFunction.Blake3.Hasher.blake3_update_preemptive
staticprivate

◆ blake3_update_rayon

readonly blake3_update_rayon_del Data.HashFunction.Blake3.Hasher.blake3_update_rayon
staticprivate

◆ lib_loader

NativeLibraryLoader Data.HashFunction.Blake3.Hasher.lib_loader
staticprivate

◆ LimitPreemptive

const int Data.HashFunction.Blake3.Hasher.LimitPreemptive = 1024
staticprivate

We are taking a limit of 1024 bytes to switch to a preemptive version, as it takes around 1μs on a x64 very recent CPU to complete, which is better aligned with the documentation of SuppressGCTransitionAttribute: Native function always executes for a trivial amount of time (less than 1 microsecond).


The documentation for this class was generated from the following file: