42 use,
intrinsic :: iso_c_binding, only : c_ptr, c_associated
48 logical :: valid = .false.
49 logical :: skip = .false.
50 class(*),
allocatable :: key
51 class(*),
allocatable :: data
58 integer,
private :: size = 0
59 integer,
private :: entries = 0
75 class(*),
intent(in) :: k
243 class(
htable_t),
intent(inout) :: this
244 integer,
value :: size
245 class(*),
target,
intent(in) :: key
246 class(*),
target,
intent(in),
optional :: data
247 class(*),
pointer :: data_ptr
253 if (
size .lt. 4)
then
257 size = ishft(1, ceiling(log(dble(size)) /
neko_m_ln2))
259 allocate(this%t(0:size))
260 this%t(:)%valid = .false.
265 if (
present(data))
then
270 allocate(this%t(i)%key, source=key)
271 allocate(this%t(i)%data, source=data_ptr)
277 class(
htable_t),
intent(inout) :: this
283 if (
allocated(this%t))
then
285 deallocate(this%t(i)%key)
286 deallocate(this%t(i)%data)
298 class(
htable_t),
intent(inout) :: this
300 if (
allocated(this%t))
then
301 this%t(:)%valid = .false.
313 entries = this%entries
326 class(
htable_t),
target,
intent(inout) :: this
327 class(*),
intent(inout) :: key
328 class(*),
intent(inout) :: data
333 i = log(1.0/this%size)/log(0.6)
337 index = this%hash(key, c**2)
338 if (index .lt. 0)
then
342 if ((.not. this%t(index)%valid) .or. &
346 if (.not. this%t(index)%valid)
then
347 this%entries = this%entries + 1
348 if (
associated(this%tail))
then
349 this%tail%next => this%t(index)
350 this%t(index)%prev => this%tail
351 this%tail => this%t(index)
353 this%head => this%t(index)
354 this%tail => this%t(index)
357 this%t(index)%valid = .true.
358 this%t(index)%skip = .false.
368 type is (
integer(
i8))
370 type is (double precision)
384 call htable_init(tmp, ishft(this%size, 1), key, data)
400 do i = 0, this%size - 1
401 if (this%t(i)%valid)
then
402 select type (datap => this%t(i)%data)
405 type is (
integer(
i8))
407 type is (double precision)
412 select type(tuplep => datap)
426 this%head => tmp%head
427 this%tail => tmp%tail
429 call move_alloc(tmp%t, this%t)
437 class(
htable_t),
intent(inout) :: this
438 class(*),
intent(inout) :: key
439 class(*),
intent(inout) :: data
441 integer :: index, i, c
444 i = log(1.0/this%size)/log(0.6)
447 index = this%hash(key, c**2)
448 if (index .lt. 0)
then
452 if (.not. this%t(index)%valid .and. &
453 .not. this%t(index)%skip)
then
456 else if ((this%t(index)%valid) .and. &
470 class(
htable_t),
intent(inout) :: this
471 class(*),
intent(inout) :: key
472 integer :: index, i, c
475 i = log(1.0/this%size)/log(0.6)
478 index = this%hash(key, c**2)
479 if (index .lt. 0)
then
483 if ((this%t(index)%valid) .and. &
486 if (
associated(this%t(index)%prev))
then
487 this%t(index)%prev%next => this%t(index)%next
489 this%head => this%t(index)%next
492 if (
associated(this%t(index)%next))
then
493 this%t(index)%next%prev => this%t(index)%prev
495 this%tail => this%t(index)%prev
498 this%t(index)%valid = .false.
499 this%t(index)%skip = .true.
500 this%entries = this%entries - 1
510 class(
htable_t),
target,
intent(inout) :: this
511 integer,
intent(in) :: idx
512 class(*),
intent(in) :: data
513 class(*),
pointer :: hdp
515 hdp => this%t(idx)%data
522 type is (
integer(i8))
524 type is (
integer(i8))
527 type is (double precision)
529 type is (double precision)
557 integer,
intent(in) :: idx
558 class(*),
intent(inout) :: data
560 select type (hdp=>this%t(idx)%data)
566 type is (
integer(i8))
568 type is (
integer(i8))
571 type is (double precision)
573 type is (double precision)
601 integer,
intent(in) :: idx
602 class(*),
intent(in) :: key
606 select type (kp=>this%t(idx)%key)
612 type is (
integer(
i8))
614 type is (
integer(
i8))
617 type is (double precision)
619 type is (double precision)
620 res = abs(kp - key) .lt. epsilon(1.0_dp)
637 res = c_associated(kp%ptr, key%ptr)
644 class(
htable_t),
target,
intent(inout) :: this
645 integer,
intent(in) :: idx
646 class(*),
intent(in) :: key
647 class(*),
pointer :: kp
649 kp => this%t(idx)%key
656 type is (
integer(i8))
658 type is (
integer(i8))
661 type is (double precision)
663 type is (double precision)
693 if (.not.
associated(this%current))
then
694 this%current => this%t%head
695 valid =
associated(this%current)
696 else if (
associated(this%current))
then
697 if (
associated(this%current, this%t%tail))
then
700 this%current => this%current%next
701 valid =
associated(this%current)
710 nullify(this%current)
719 class(*),
intent(inout) :: data
720 class(*),
pointer :: hdp
722 hdp => this%current%data
729 type is (
integer(i8))
731 type is (
integer(i8))
734 type is (double precision)
736 type is (double precision)
768 integer,
value :: size
769 class(*),
intent(inout),
optional :: data
772 if (
present(data))
then
783 integer,
intent(inout) :: key
784 class(*),
intent(inout) :: data
793 integer,
intent(inout) :: key
794 class(*),
intent(inout) :: data
804 class(*),
intent(in) :: k
807 integer(kind=i8) :: tmp
808 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
809 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
810 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
811 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
812 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
813 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
818 tmp = (k + m1) + ishft(k, 12)
819 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
820 tmp = (tmp + m3) + ishft(tmp, 5)
821 tmp = ieor((tmp + m4), ishft(tmp, 9))
822 tmp = (tmp + m5) + ishft(tmp, 3)
823 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
824 tmp = modulo(tmp + int(c,
i8), int(this%size,
i8))
834 integer,
intent(inout) :: key
853 nullify(this%current)
859 integer,
pointer :: value
861 select type (hdp => this%current%data)
865 call neko_error(
'Key and data of different kind (i4)')
873 integer,
pointer :: key
875 select type (kp => this%current%key)
890 integer,
value :: size
891 class(*),
intent(inout),
optional :: data
892 integer(kind=i8) :: key
894 if (
present(data))
then
905 integer(kind=i8),
intent(inout) :: key
906 class(*),
intent(inout) :: data
915 integer(kind=i8),
intent(inout) :: key
916 class(*),
intent(inout) :: data
926 class(*),
intent(in) :: k
929 integer(kind=i8) :: tmp
930 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
931 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
932 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
933 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
934 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
935 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
938 type is (
integer(
i8))
939 tmp = (k + m1) + ishft(k, 12)
940 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
941 tmp = (tmp + m3) + ishft(tmp, 5)
942 tmp = ieor((tmp + m4), ishft(tmp, 9))
943 tmp = (tmp + m5) + ishft(tmp, 3)
944 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
945 hash = int(modulo(tmp, int(this%size,
i8)),
i4)
947 hash = int(modulo((k * 2654435761_i8) + int(c,
i8), &
948 int(this%size,
i8)),
i4)
957 integer(kind=i8),
intent(inout) :: key
976 nullify(this%current)
982 integer(kind=i8),
pointer :: value
984 select type (hdp => this%current%data)
985 type is (
integer(
i8))
988 call neko_error(
'Key and data of different kind (i8)')
996 integer(kind=i8),
pointer :: key
1001 select type(hti => this)
1003 select type (kp => hti%current%key)
1004 type is (
integer(
i8))
1022 integer,
value :: size
1023 class(*),
intent(inout),
optional :: data
1024 real(kind=
dp) :: key
1026 if (
present(data))
then
1037 real(kind=
dp),
intent(inout) :: key
1038 class(*),
intent(inout) :: data
1047 real(kind=
dp),
intent(inout) :: key
1048 class(*),
intent(inout) :: data
1058 class(*),
intent(in) :: k
1062 type is (double precision)
1063 hash = modulo(floor((2d0 * abs(fraction(k)) - 1d0) * 2**16) + c, this%size)
1072 real(kind=
dp),
intent(inout) :: key
1092 nullify(this%current)
1098 real(kind=
dp),
pointer ::
value
1100 select type (hdp => this%current%data)
1101 type is (double precision)
1104 call neko_error(
'Key and data of different kind (r8)')
1112 real(kind=
dp),
pointer :: key
1114 select type (kp => this%current%key)
1115 type is (double precision)
1129 integer,
value :: size
1130 class(*),
intent(inout),
optional :: data
1133 if (
present(data))
then
1144 type(
point_t),
intent(inout) :: key
1145 class(*),
intent(inout) :: data
1154 type(
point_t),
intent(inout) :: key
1155 class(*),
intent(inout) :: data
1165 class(*),
intent(in) :: k
1168 integer(kind=i8) :: hash2, tmp, mult
1169 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
1170 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
1171 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
1172 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
1173 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
1174 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
1179 hash2 = int(z
'345678')
1181 tmp = transfer(k%x(i), tmp)
1182 tmp = (tmp + m1) + ishft(tmp, 12)
1183 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1184 tmp = (tmp + m3) + ishft(tmp, 5)
1185 tmp = ieor((tmp + m4), ishft(tmp, 9))
1186 tmp = (tmp + m5) + ishft(tmp, 3)
1187 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1188 hash2 = ieor(hash2, tmp) * mult
1189 mult = mult + 82520 + 8
1191 hash2 = hash2 + 97531
1192 hash2 = modulo(hash2 + int(c,
i8), int(this%size,
i8))
1193 hash = int(hash2,
i4)
1203 type(
point_t),
intent(inout) :: key
1223 nullify(this%current)
1229 type(
point_t),
pointer :: value
1231 select type (hdp => this%current%data)
1235 call neko_error(
'Key and data of different kind (pt)')
1245 select type (kp => this%current%key)
1260 integer,
value :: size
1261 class(*),
intent(inout),
optional :: data
1264 if (
present(data))
then
1276 class(*),
intent(inout) :: data
1286 class(*),
intent(inout) :: data
1296 class(*),
intent(in) :: k
1299 integer(kind=i8) :: tmp, hash2, mult
1300 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
1301 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
1302 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
1303 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
1304 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
1305 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
1309 mult = int(1000003,
i8)
1310 hash2 = int(z
'345678',
i8)
1312 tmp = int(k%x(i),
i8)
1313 tmp = (tmp + m1) + ishft(tmp, 12)
1314 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1315 tmp = (tmp + m3) + ishft(tmp, 5)
1316 tmp = ieor((tmp + m4), ishft(tmp, 9))
1317 tmp = (tmp + m5) + ishft(tmp, 3)
1318 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1319 hash2 = ieor(hash2, tmp) * mult
1320 mult = mult + 82520_i8 + 4_i8
1322 hash2 = hash2 + 97531_i8
1323 hash2 = modulo(hash2 + int(c,
i8), int(this%size,
i8))
1324 hash = int(hash2,
i4)
1352 nullify(this%current)
1360 select type (hdp => this%current%data)
1364 call neko_error(
'Key and data of different kind (i4t2)')
1374 select type (kp => this%current%key)
1389 integer,
value :: size
1390 class(*),
intent(inout),
optional :: data
1393 if (
present(data))
then
1405 class(*),
intent(inout) :: data
1415 class(*),
intent(inout) :: data
1425 class(*),
intent(in) :: k
1428 integer(kind=i8) :: tmp, hash2, mult
1429 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
1430 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
1431 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
1432 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
1433 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
1434 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
1438 mult = int(1000003,
i8)
1439 hash2 = int(z
'345678',
i8)
1441 tmp = int(k%x(i),
i8)
1442 tmp = (tmp + m1) + ishft(tmp, 12)
1443 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1444 tmp = (tmp + m3) + ishft(tmp, 5)
1445 tmp = ieor((tmp + m4), ishft(tmp, 9))
1446 tmp = (tmp + m5) + ishft(tmp, 3)
1447 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1448 hash2 = ieor(hash2, tmp) * mult
1449 mult = mult + 82520_i8 + 8_i8
1451 hash2 = hash2 + 97531_i8
1452 hash2 = modulo(hash2 + int(c,
i8), int(this%size,
i8))
1453 hash = int(hash2,
i4)
1481 nullify(this%current)
1489 select type (hdp => this%current%data)
1493 call neko_error(
'Key and data of different kind (i4t4)')
1506 select type(hti => this)
1508 select type (kp => hti%current%key)
1515 call neko_error(
'Corrupt htable iter. (i4t4)')
1526 integer,
value :: size
1527 class(*),
intent(inout),
optional :: data
1530 if (
present(data))
then
1541 type(
h_cptr_t),
intent(inout) :: key
1542 class(*),
intent(inout) :: data
1551 type(
h_cptr_t),
intent(inout) :: key
1552 class(*),
intent(inout) :: data
1562 class(*),
intent(in) :: k
1565 integer(kind=i8) :: k_int
1569 k_int = transfer(k%ptr, k_int)
1570 hash = int(modulo(k_int * 2654435761_i8 + int(c,
i8),&
1571 int(this%size,
i8)),
i4)
1580 type(
h_cptr_t),
intent(inout) :: key
1599 nullify(this%current)
1605 class(*),
pointer :: hdp
1608 hdp => this%current%data
1613 call neko_error(
'Key and data of different kind (cptr)')
1621 class(*),
pointer :: kp
1624 kp => this%current%key
Implements a hash table ADT.
subroutine htable_i4t4_init(this, size, data)
Initialize an integer 4-tuple hash table.
subroutine htable_iter_r8_init(this, t)
Initialize a double precision based hash table iterator.
subroutine htable_clear(this)
Clear all entries in a hash table.
subroutine htable_pt_init(this, size, data)
Initialize a point based hash table.
type(tuple_i4_t) function, pointer htable_iter_i4t2_key(this)
Return the current key of integer based 2-tuple hash table iterator.
subroutine htable_iter_i8_free(this)
Destroy an integer*8 based hash table iterator.
subroutine htable_i4_set(this, key, data)
Insert an integer into the hash table.
type(tuple4_i4_t) function, pointer htable_iter_i4t4_value(this)
Return the current value of integer based 4-tuple hash table iterator.
integer function, pointer htable_iter_i4_value(this)
Return the current value of the integer based hash table iterator.
subroutine htable_r8_init(this, size, data)
Initialize a double precision based hash table.
integer(kind=i8) function, pointer htable_iter_i8_key(this)
Return the current key of the integer*8 based hash table iterator.
type(point_t) function, pointer htable_iter_pt_key(this)
Return the current key of the point based hash table iterator.
pure integer function htable_r8_hash(this, k, c)
Hash function for a double precision based hash table.
subroutine htable_cptr_init(this, size, data)
Initialize a C pointer based hash table.
pure integer function htable_i4_hash(this, k, c)
Hash function for an integer based hash table.
subroutine htable_iter_cptr_free(this)
Destroy a C pointer based hash table iterator.
subroutine htable_iter_pt_free(this)
Destroy a point based hash table iterator.
subroutine htable_i4t4_set(this, key, data)
Insert an integer 4-tuple into the hash table.
subroutine htable_i8_init(this, size, data)
Initialize an integer*8 based hash table.
subroutine htable_pt_remove(this, key)
Remove a point with key key from the hash table.
subroutine htable_cptr_remove(this, key)
Remove a C pointer with key key from the hash table.
subroutine htable_free(this)
Destroy a hash table.
subroutine htable_iter_data(this, data)
Return the data at the current iterator position.
pure integer function htable_size(this)
Return total size of htable.
subroutine htable_get_data(this, idx, data)
Return data at idx in value.
integer function htable_r8_get(this, key, data)
Retrive a double precision float with key key from the hash table.
pure integer function htable_i8_hash(this, k, c)
Hash function for an integer*8 based hash table.
subroutine htable_i4t4_remove(this, key)
Remove an integer 4-tuple with key key from the hash table.
integer function htable_get(this, key, data)
Retrieve data associated with key into the hash table.
integer function htable_i8_get(this, key, data)
Retrive an integer*8 with key key from the hash table.
integer function htable_pt_get(this, key, data)
Retrive a point with key key from the hash table.
subroutine htable_remove(this, key)
Remove a key from the hash table.
subroutine htable_set_data(this, idx, data)
Set data at idx to value.
real(kind=dp) function, pointer htable_iter_r8_key(this)
Return the current key of the double precision based hash table iterator.
subroutine htable_iter_pt_init(this, t)
Initialize a point based hash table iterator.
integer function htable_i4_get(this, key, data)
Retrive an integer with key key from the hash table.
type(h_cptr_t) function, pointer htable_iter_cptr_value(this)
Return the current value of C pointer based hash table iterator.
type(tuple_i4_t) function, pointer htable_iter_i4t2_value(this)
Return the current value of integer based 2-tuple hash table iterator.
logical function htable_iter_next(this)
Advance the iterator to the next valid table entry.
integer function htable_cptr_get(this, key, data)
Retrive a C pointer with key key from the hash table.
subroutine htable_i8_set(this, key, data)
Insert an integer*8 into the hash table.
subroutine htable_r8_remove(this, key)
Remove a double precision key key from the hash table.
subroutine htable_iter_i4t2_free(this)
Destroy an integer 2-tuple based hash table iterator.
subroutine htable_r8_set(this, key, data)
Insert a double precision key (with data) into the hash table.
type(point_t) function, pointer htable_iter_pt_value(this)
Return the current value of the point based hash table iterator.
integer function htable_i4t4_get(this, key, data)
Retrive an integer 4-tuple with key key from the hash table.
subroutine htable_i4t2_set(this, key, data)
Insert an integer 2-tuple into the hash table.
pure integer function htable_num_entries(this)
Return number of entries in the table.
type(tuple4_i4_t) function, pointer htable_iter_i4t4_key(this)
Return the current key of integer based 4-tuple hash table iterator.
recursive subroutine htable_set(this, key, data)
Insert tuple (key, value) into the hash table.
pure logical function htable_eq_key(this, idx, key)
Compare key at idx to key.
subroutine htable_i4t2_remove(this, key)
Remove an integer 2-tuple with key key from the hash table.
subroutine htable_set_key(this, idx, key)
Set key at idx to key.
subroutine htable_iter_i8_init(this, t)
Initialize an integer*8 based hash table iterator.
pure integer function htable_i4t4_hash(this, k, c)
Hash function for an integer 4-tuple hash table.
pure integer function htable_pt_hash(this, k, c)
Hash function for a point based hash table.
integer function, pointer htable_iter_i4_key(this)
Return the current key of the integer based hash table iterator.
subroutine htable_iter_i4_init(this, t)
Initialize an integer based hash table iterator.
subroutine htable_init(this, size, key, data)
Initialize a hash table of type data.
subroutine htable_i4t2_init(this, size, data)
Initialize an integer 2-tuple hash table.
subroutine htable_cptr_set(this, key, data)
Insert a C pointer into the hash table.
subroutine htable_iter_i4t4_free(this)
Destroy an integer 4-tuple based hash table iterator.
subroutine htable_i4_remove(this, key)
Remove an integer with key key from the hash table.
subroutine htable_iter_cptr_init(this, t)
Initialize a C pointer based hash table iterator.
integer(kind=i8) function, pointer htable_iter_i8_value(this)
Return the current value of the integer*8 based hash table iterator.
integer function htable_i4t2_get(this, key, data)
Retrive an integer 2-tuple with key key from the hash table.
subroutine htable_iter_i4t4_init(this, t)
Initialize an integer 4-tuple based hash table iterator.
subroutine htable_i8_remove(this, key)
Remove an integer*8 with key key from the hash table.
subroutine htable_i4_init(this, size, data)
Initialize an integer based hash table.
pure integer function htable_cptr_hash(this, k, c)
Hash function for an integer 4-tuple hash table.
subroutine htable_pt_set(this, key, data)
Insert a point key (with data) into the hash table.
subroutine htable_iter_reset(this)
Reset an iterator.
subroutine htable_iter_i4_free(this)
Destroy an integer based hash table iterator.
type(h_cptr_t) function, pointer htable_iter_cptr_key(this)
Return the current key of a C pointer based hash table iterator.
subroutine htable_iter_r8_free(this)
Destroy a double precision based hash table iterator.
pure integer function htable_i4t2_hash(this, k, c)
Hash function for an integer 2-tuple hash table.
subroutine htable_iter_i4t2_init(this, t)
Initialize an integer 2-tuple based hash table iterator.
real(kind=dp) function, pointer htable_iter_r8_value(this)
Return the current value of the double precision based hash table iterator.
real(kind=rp), parameter, public neko_m_ln2
integer, parameter, public i8
integer, parameter, public i4
integer, parameter, public dp
Hash table entry, tuple (key, data)
C pointer based hash table.
Integer based hash table.
Integer 2-tuple based hash table.
Integer 4-tuple based hash table.
Integer*8 based hash table.
Iterator for a C pointer based hash table.
Iterator for an integer based hash table.
Iterator for an integer based 2-tuple hash table.
Iterator for an integer based 4-tuple hash table.
Iterator for an integer*8 based hash table.
Iterator for a point based hash table.
Iterator for a double precision based hash table.
Base type for a hash table iterator.
Double precision based hash table.
Base type for a hash table.
A point in with coordinates .
Base type for an n-tuple.