HASH: Add generic function xxh64().
This function calculates the XXH64 has using a sequence of bytes, or integer(kind=1) vector. Signed-off-by: Grzegorz Kowal <grzegorz@amuncode.org>
This commit is contained in:
parent
5696b87e37
commit
3690d5c3bf
109
sources/hash.F90
109
sources/hash.F90
@ -55,7 +55,7 @@ module hash
|
||||
|
||||
! declare public subroutines
|
||||
!
|
||||
public :: xxh64_integer, xxh64_long, xxh64_double, xxh64_complex
|
||||
public :: xxh64, xxh64_integer, xxh64_long, xxh64_double, xxh64_complex
|
||||
|
||||
!- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
!
|
||||
@ -70,6 +70,113 @@ module hash
|
||||
!
|
||||
!===============================================================================
|
||||
!
|
||||
! function XXH64:
|
||||
! --------------
|
||||
!
|
||||
! Function calculates XXH64 hash for a given sequence of bytes.
|
||||
!
|
||||
! Arguments:
|
||||
!
|
||||
! input - the input sequence of bytes;
|
||||
!
|
||||
!===============================================================================
|
||||
!
|
||||
integer(kind=8) function xxh64(input) result(hash)
|
||||
|
||||
implicit none
|
||||
|
||||
! subroutine arguments
|
||||
!
|
||||
integer(kind=1), dimension(:), intent(in) :: input
|
||||
|
||||
! local variables
|
||||
!
|
||||
integer(kind=8) :: length, remaining, offset
|
||||
|
||||
! local arrays
|
||||
!
|
||||
integer(kind=8), dimension(4) :: lane, chunk
|
||||
|
||||
!-------------------------------------------------------------------------------
|
||||
!
|
||||
length = size(input)
|
||||
hash = 0_8
|
||||
offset = 1_8
|
||||
remaining = length
|
||||
|
||||
if (remaining >= 32_8) then
|
||||
lane(1) = seed + prime1 + prime2
|
||||
lane(2) = seed + prime2
|
||||
lane(3) = seed + 0_8
|
||||
lane(4) = seed - prime1
|
||||
|
||||
do while (remaining >= 32_8)
|
||||
chunk(1:4) = transfer(input(offset:offset+31), 1_8, 4)
|
||||
|
||||
lane(1) = xxh64_round(lane(1), chunk(1))
|
||||
lane(2) = xxh64_round(lane(2), chunk(2))
|
||||
lane(3) = xxh64_round(lane(3), chunk(3))
|
||||
lane(4) = xxh64_round(lane(4), chunk(4))
|
||||
|
||||
offset = offset + 32_8
|
||||
remaining = remaining - 32_8
|
||||
end do
|
||||
|
||||
hash = xxh64_rotl(lane(1), 1) + xxh64_rotl(lane(2), 7) + &
|
||||
xxh64_rotl(lane(3), 12) + xxh64_rotl(lane(4), 18)
|
||||
|
||||
hash = xxh64_merge(hash, lane(1))
|
||||
hash = xxh64_merge(hash, lane(2))
|
||||
hash = xxh64_merge(hash, lane(3))
|
||||
hash = xxh64_merge(hash, lane(4))
|
||||
|
||||
else
|
||||
hash = seed + prime5
|
||||
end if
|
||||
|
||||
hash = hash + length
|
||||
|
||||
do while (remaining >= 8_8)
|
||||
chunk(1) = transfer(input(offset:offset+7), 1_8)
|
||||
hash = ieor(hash, xxh64_round(0_8, chunk(1)))
|
||||
hash = xxh64_rotl(hash, 27)
|
||||
hash = hash * prime1 + prime4
|
||||
|
||||
offset = offset + 8_8
|
||||
remaining = remaining - 8_8
|
||||
end do
|
||||
|
||||
if (remaining >= 4) then
|
||||
chunk(1) = transfer((/ input(offset:offset+3), 0_1, 0_1, 0_1, 0_1 /), 1_8)
|
||||
hash = ieor(hash, chunk(1) * prime1)
|
||||
hash = xxh64_rotl(hash, 23)
|
||||
hash = hash * prime2 + prime3
|
||||
|
||||
offset = offset + 4_8
|
||||
remaining = remaining - 4_8
|
||||
end if
|
||||
|
||||
do while (remaining > 0_8)
|
||||
chunk(1) = transfer((/ input(offset), 0_1, 0_1, 0_1, &
|
||||
0_1, 0_1, 0_1, 0_1 /), 1_8)
|
||||
hash = ieor(hash, chunk(1) * prime5)
|
||||
hash = xxh64_rotl(hash, 11)
|
||||
hash = hash * prime1
|
||||
|
||||
offset = offset + 1_8
|
||||
remaining = remaining - 1_8
|
||||
end do
|
||||
|
||||
hash = xxh64_aval(hash)
|
||||
|
||||
return
|
||||
|
||||
!-------------------------------------------------------------------------------
|
||||
!
|
||||
end function xxh64
|
||||
!
|
||||
!===============================================================================
|
||||
!
|
||||
! function XXH64_INTEGER:
|
||||
! ----------------------
|
||||
!
|
||||
|
Loading…
x
Reference in New Issue
Block a user