@@ -149,54 +149,38 @@ public static ulong Hash64(ReadOnlySpan<byte> buffer, ulong seed = 0)
149149 /// <returns>Computed 64-bit hash value.</returns>
150150 public static ulong Hash64 ( Stream stream , ulong seed = 0 )
151151 {
152- const int stripeLength = 32 ;
153- const int readBufferSize = stripeLength * 1024 ; // 32kb buffer length
154-
155- ulong acc ;
152+ const int readBufferSize = State64 . StripeLength * 1024 ; // 32kb buffer length
156153
157154 var buffer = new byte [ readBufferSize ] . AsSpan ( ) ;
158- int readBytes = stream . Read ( buffer ) ;
159- ulong len = ( ulong ) readBytes ;
160-
161- int offset = 0 ;
162- if ( readBytes < stripeLength )
155+ var state = new State64 ( seed ) ;
156+ int bytesRead ;
157+ while ( ( bytesRead = stream . Read ( buffer ) ) > 0 )
163158 {
164- acc = seed + prime64v5 ;
165- goto Exit ;
159+ state . Update ( buffer [ ..bytesRead ] ) ;
166160 }
167161
168- var ( acc1 , acc2 , acc3 , acc4 ) = initAccumulators64 ( seed ) ;
169- do
162+ return state . Result ( ) ;
163+ }
164+
165+ /// <summary>
166+ /// Generate a 64-bit xxHash value from a stream.
167+ /// </summary>
168+ /// <param name="stream">Input stream.</param>
169+ /// <param name="seed">Optional seed.</param>
170+ /// <returns>Computed 64-bit hash value.</returns>
171+ public static async Task < ulong > Hash64Async ( Stream stream , ulong seed = 0 )
172+ {
173+ const int readBufferSize = State64 . StripeLength * 1024 ; // 32kb buffer length
174+
175+ var buffer = new byte [ readBufferSize ] ;
176+ var state = new State64 ( seed ) ;
177+ int bytesRead ;
178+ while ( ( bytesRead = await stream . ReadAsync ( buffer ) ) > 0 )
170179 {
171- do
172- {
173- int end = offset + stripeLength ;
174- acc = processStripe64 (
175- buffer [ offset ..end ] ,
176- ref acc1 ,
177- ref acc2 ,
178- ref acc3 ,
179- ref acc4 ) ;
180- offset = end ;
181- readBytes -= stripeLength ;
182- }
183- while ( readBytes >= stripeLength ) ;
184-
185- // read more if the alignment is intact
186- if ( readBytes == 0 )
187- {
188- readBytes = stream . Read ( buffer ) ;
189- offset = 0 ;
190- len += ( ulong ) readBytes ;
191- }
180+ state . Update ( buffer . AsSpan ( 0 , bytesRead ) ) ;
192181 }
193- while ( readBytes >= stripeLength ) ;
194182
195- Exit :
196- acc += len ;
197- acc = processRemaining64 ( buffer [ offset ..( offset + readBytes ) ] , acc ) ;
198-
199- return avalanche64 ( acc ) ;
183+ return state . Result ( ) ;
200184 }
201185
202186 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
0 commit comments