55using  System . Buffers ; 
66using  System . Buffers . Binary ; 
77using  System . Runtime . CompilerServices ; 
8+ using  System . Runtime . InteropServices ; 
89using  System . Text ; 
910using  System . Threading ; 
1011
@@ -149,17 +150,32 @@ private static void ComputeHash(ReadOnlySpan<byte> data,
149150                                        out  uint  hash1 , 
150151                                        out  uint  hash2 ) 
151152        { 
152-             uint  a ,  b ,  c ; 
153+             uint  len  =  ( uint ) data . Length ; 
154+             uint  a  =  0xDEADBEEF  +  len  +  seed1 ; 
155+             uint  b  =  a ; 
156+             uint  c  =  a  +  seed2 ; 
153157
154-             a  =  b  =  c  =  ( uint ) ( 0xdeadbeef  +  data . Length  +  seed1 ) ; 
155-             c  +=  seed2 ; 
158+             int  tripletCount  =  data . Length  >  12  ?  ( data . Length  -  1 )  /  12  :  0 ; 
156159
157-             int  index  =  0 ,  size  =  data . Length ; 
158-             while  ( size  >  12 ) 
160+             int  regionBytes  =  tripletCount  *  12 ;  // must be divisible by 4 
161+             ReadOnlySpan < byte >  region  =  data . Slice ( 0 ,  regionBytes ) ; 
162+             ReadOnlySpan < uint >  words  =  MemoryMarshal . Cast < byte ,  uint > ( region ) ; 
163+ 
164+             int  i  =  0 ; 
165+             for  ( ;  i  <  tripletCount ;  i ++ ) 
159166            { 
160-                 a  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( index ) ) ; 
161-                 b  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( index  +  4 ) ) ; 
162-                 c  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( index  +  8 ) ) ; 
167+                 int  idx  =  i  *  3 ; 
168+                 uint  w0  =  BitConverter . IsLittleEndian  ?  words [ idx ]  :  BinaryPrimitives . ReverseEndianness ( words [ idx ] ) ; 
169+                 uint  w1  =  BitConverter . IsLittleEndian 
170+                     ?  words [ idx  +  1 ] 
171+                     :  BinaryPrimitives . ReverseEndianness ( words [ idx  +  1 ] ) ; 
172+                 uint  w2  =  BitConverter . IsLittleEndian 
173+                     ?  words [ idx  +  2 ] 
174+                     :  BinaryPrimitives . ReverseEndianness ( words [ idx  +  2 ] ) ; 
175+ 
176+                 a  +=  w0 ; 
177+                 b  +=  w1 ; 
178+                 c  +=  w2 ; 
163179
164180                a  -=  c ; 
165181                a  ^=  ( c  <<  4 )  |  ( c  >>  28 ) ; 
@@ -184,51 +200,50 @@ private static void ComputeHash(ReadOnlySpan<byte> data,
184200                c  -=  b ; 
185201                c  ^=  ( b  <<  4 )  |  ( b  >>  28 ) ; 
186202                b  +=  a ; 
187- 
188-                 index  +=  12 ; 
189-                 size  -=  12 ; 
190203            } 
191204
205+             int  byteIndex  =  regionBytes ; 
206+             int  size  =  data . Length  -  byteIndex ; 
192207            switch  ( size ) 
193208            { 
194209                case  12 : 
195-                     a  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( index ) ) ; 
196-                     b  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( index  +  4 ) ) ; 
197-                     c  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( index  +  8 ) ) ; 
210+                     a  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( byteIndex ) ) ; 
211+                     b  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( byteIndex  +  4 ) ) ; 
212+                     c  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( byteIndex  +  8 ) ) ; 
198213                    break ; 
199214                case  11 : 
200-                     c  +=  ( ( uint ) data [ index  +  10 ] )  <<  16 ; 
215+                     c  +=  ( uint ) data [ byteIndex  +  10 ]  <<  16 ; 
201216                    goto  case  10 ; 
202217                case  10 : 
203-                     c  +=  ( ( uint ) data [ index  +  9 ] )  <<  8 ; 
218+                     c  +=  ( uint ) data [ byteIndex  +  9 ]  <<  8 ; 
204219                    goto  case  9 ; 
205220                case  9 : 
206-                     c  +=  ( uint ) data [ index  +  8 ] ; 
221+                     c  +=  data [ byteIndex  +  8 ] ; 
207222                    goto  case  8 ; 
208223                case  8 : 
209-                     b  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( index  +  4 ) ) ; 
210-                     a  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( index ) ) ; 
224+                     b  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( byteIndex  +  4 ) ) ; 
225+                     a  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( byteIndex ) ) ; 
211226                    break ; 
212227                case  7 : 
213-                     b  +=  ( ( uint ) data [ index  +  6 ] )  <<  16 ; 
228+                     b  +=  ( uint ) data [ byteIndex  +  6 ]  <<  16 ; 
214229                    goto  case  6 ; 
215230                case  6 : 
216-                     b  +=  ( ( uint ) data [ index  +  5 ] )  <<  8 ; 
231+                     b  +=  ( uint ) data [ byteIndex  +  5 ]  <<  8 ; 
217232                    goto  case  5 ; 
218233                case  5 : 
219-                     b  +=  ( uint ) data [ index  +  4 ] ; 
234+                     b  +=  data [ byteIndex  +  4 ] ; 
220235                    goto  case  4 ; 
221236                case  4 : 
222-                     a  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( index ) ) ; 
237+                     a  +=  BinaryPrimitives . ReadUInt32LittleEndian ( data . Slice ( byteIndex ) ) ; 
223238                    break ; 
224239                case  3 : 
225-                     a  +=  ( ( uint ) data [ index  +  2 ] )  <<  16 ; 
240+                     a  +=  ( uint ) data [ byteIndex  +  2 ]  <<  16 ; 
226241                    goto  case  2 ; 
227242                case  2 : 
228-                     a  +=  ( ( uint ) data [ index  +  1 ] )  <<  8 ; 
243+                     a  +=  ( uint ) data [ byteIndex  +  1 ]  <<  8 ; 
229244                    goto  case  1 ; 
230245                case  1 : 
231-                     a  +=  ( uint ) data [ index ] ; 
246+                     a  +=  data [ byteIndex ] ; 
232247                    break ; 
233248                case  0 : 
234249                    hash1  =  c ; 
0 commit comments