generates the hash of a string and the index in the table
Note
http://en.wikipedia.org/wiki/Hash_table http://www.burtleburtle.net/bob/hash/doobs.html However, since fortran doesn't have an unsigned 4 byte int we compute it using an integer with the appropriate range we return already the index in the table as a final result
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer, | intent(in), | DIMENSION(:) | :: | key |
FUNCTION joaat_hash(key) RESULT(hash_index) !! generates the hash of a string and the index in the table !! @note !! http://en.wikipedia.org/wiki/Hash_table !! http://www.burtleburtle.net/bob/hash/doobs.html !! However, since fortran doesn't have an unsigned 4 byte int !! we compute it using an integer with the appropriate range !! we return already the index in the table as a final result ! LIBXSMM: at least v1.9.0-6 is required #if defined(__LIBXSMM) && TO_VERSION(1, 10) <= TO_VERSION(LIBXSMM_CONFIG_VERSION_MAJOR, LIBXSMM_CONFIG_VERSION_MINOR) USE libxsmm, ONLY: libxsmm_hash INTEGER, PARAMETER :: seed = 0 INTEGER, DIMENSION(:), INTENT(IN) :: key !! a string of any length INTEGER :: hash_index hash_index = libxsmm_hash(key, seed) #else INTEGER, DIMENSION(:), INTENT(IN) :: key INTEGER :: hash_index INTEGER(KIND=int_8), PARAMETER :: b32 = 2_int_8**32 - 1_int_8 INTEGER :: i, j INTEGER(KIND=int_8) :: byte, hash hash = 0_int_8 DO i = 1, SIZE(key) DO j = 0, 3 byte = IAND(ISHFT(key(i), -j*8), 255) hash = IAND(hash + byte, b32) hash = IAND(hash + IAND(ISHFT(hash, 10), b32), b32) hash = IAND(IEOR(hash, IAND(ISHFT(hash, -6), b32)), b32) END DO END DO hash = IAND(hash + IAND(ISHFT(hash, 3), b32), b32) hash = IAND(IEOR(hash, IAND(ISHFT(hash, -11), b32)), b32) hash = IAND(hash + IAND(ISHFT(hash, 15), b32), b32) ! In fortran 4-byte-integers have only 31 bits because they are signed ! In fortran the rightmost (least significant) bit is in position 0 hash_index = INT(IBCLR(hash, 31)) #endif END FUNCTION joaat_hash