58 use,
intrinsic :: iso_c_binding, only : c_ptr, c_associated
64 logical :: valid = .false.
65 logical :: skip = .false.
66 class(*),
allocatable :: key
67 class(*),
allocatable :: data
74 integer,
private :: size = 0
75 integer,
private :: entries = 0
91 class(*),
intent(in) :: k
259 class(
htable_t),
intent(inout) :: this
260 integer,
value :: size
261 class(*),
target,
intent(in) :: key
262 class(*),
target,
intent(in),
optional :: data
263 class(*),
pointer :: data_ptr
269 if (
size .lt. 4)
then
273 size = ishft(1, ceiling(log(dble(size)) /
neko_m_ln2))
275 allocate(this%t(0:size))
276 this%t(:)%valid = .false.
281 if (
present(data))
then
286 allocate(this%t(i)%key, source=key)
287 allocate(this%t(i)%data, source=data_ptr)
293 class(
htable_t),
intent(inout) :: this
299 if (
allocated(this%t))
then
301 deallocate(this%t(i)%key)
302 deallocate(this%t(i)%data)
314 class(
htable_t),
intent(inout) :: this
316 if (
allocated(this%t))
then
317 this%t(:)%valid = .false.
329 entries = this%entries
342 class(
htable_t),
target,
intent(inout) :: this
343 class(*),
intent(inout) :: key
344 class(*),
intent(inout) :: data
349 i = log(1.0/this%size)/log(0.6)
353 index = this%hash(key, c**2)
354 if (index .lt. 0)
then
358 if ((.not. this%t(index)%valid) .or. &
362 if (.not. this%t(index)%valid)
then
363 this%entries = this%entries + 1
364 if (
associated(this%tail))
then
365 this%tail%next => this%t(index)
366 this%t(index)%prev => this%tail
367 this%tail => this%t(index)
369 this%head => this%t(index)
370 this%tail => this%t(index)
373 this%t(index)%valid = .true.
374 this%t(index)%skip = .false.
384 type is (
integer(
i8))
386 type is (double precision)
400 call htable_init(tmp, ishft(this%size, 1), key, data)
416 do i = 0, this%size - 1
417 if (this%t(i)%valid)
then
418 select type (datap => this%t(i)%data)
421 type is (
integer(
i8))
423 type is (double precision)
428 select type(tuplep => datap)
442 this%head => tmp%head
443 this%tail => tmp%tail
445 call move_alloc(tmp%t, this%t)
453 class(
htable_t),
intent(inout) :: this
454 class(*),
intent(inout) :: key
455 class(*),
intent(inout) :: data
457 integer :: index, i, c
460 i = log(1.0/this%size)/log(0.6)
463 index = this%hash(key, c**2)
464 if (index .lt. 0)
then
468 if (.not. this%t(index)%valid .and. &
469 .not. this%t(index)%skip)
then
472 else if ((this%t(index)%valid) .and. &
486 class(
htable_t),
intent(inout) :: this
487 class(*),
intent(inout) :: key
488 integer :: index, i, c
491 i = log(1.0/this%size)/log(0.6)
494 index = this%hash(key, c**2)
495 if (index .lt. 0)
then
499 if ((this%t(index)%valid) .and. &
502 if (
associated(this%t(index)%prev))
then
503 this%t(index)%prev%next => this%t(index)%next
505 this%head => this%t(index)%next
508 if (
associated(this%t(index)%next))
then
509 this%t(index)%next%prev => this%t(index)%prev
511 this%tail => this%t(index)%prev
514 this%t(index)%valid = .false.
515 this%t(index)%skip = .true.
516 this%entries = this%entries - 1
526 class(
htable_t),
target,
intent(inout) :: this
527 integer,
intent(in) :: idx
528 class(*),
intent(in) :: data
529 class(*),
pointer :: hdp
531 hdp => this%t(idx)%data
538 type is (
integer(i8))
540 type is (
integer(i8))
543 type is (double precision)
545 type is (double precision)
573 integer,
intent(in) :: idx
574 class(*),
intent(inout) :: data
576 select type (hdp=>this%t(idx)%data)
582 type is (
integer(i8))
584 type is (
integer(i8))
587 type is (double precision)
589 type is (double precision)
617 integer,
intent(in) :: idx
618 class(*),
intent(in) :: key
622 select type (kp=>this%t(idx)%key)
628 type is (
integer(
i8))
630 type is (
integer(
i8))
633 type is (double precision)
635 type is (double precision)
636 res = abs(kp - key) .lt. epsilon(1.0_dp)
653 res = c_associated(kp%ptr, key%ptr)
660 class(
htable_t),
target,
intent(inout) :: this
661 integer,
intent(in) :: idx
662 class(*),
intent(in) :: key
663 class(*),
pointer :: kp
665 kp => this%t(idx)%key
672 type is (
integer(i8))
674 type is (
integer(i8))
677 type is (double precision)
679 type is (double precision)
709 if (.not.
associated(this%current))
then
710 this%current => this%t%head
711 valid =
associated(this%current)
712 else if (
associated(this%current))
then
713 if (
associated(this%current, this%t%tail))
then
716 this%current => this%current%next
717 valid =
associated(this%current)
726 nullify(this%current)
735 class(*),
intent(inout) :: data
736 class(*),
pointer :: hdp
738 hdp => this%current%data
745 type is (
integer(i8))
747 type is (
integer(i8))
750 type is (double precision)
752 type is (double precision)
784 integer,
value :: size
785 class(*),
intent(inout),
optional :: data
788 if (
present(data))
then
799 integer,
intent(inout) :: key
800 class(*),
intent(inout) :: data
809 integer,
intent(inout) :: key
810 class(*),
intent(inout) :: data
820 class(*),
intent(in) :: k
823 integer(kind=i8) :: tmp
824 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
825 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
826 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
827 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
828 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
829 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
834 tmp = (k + m1) + ishft(k, 12)
835 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
836 tmp = (tmp + m3) + ishft(tmp, 5)
837 tmp = ieor((tmp + m4), ishft(tmp, 9))
838 tmp = (tmp + m5) + ishft(tmp, 3)
839 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
840 tmp = modulo(tmp + int(c,
i8), int(this%size,
i8))
850 integer,
intent(inout) :: key
869 nullify(this%current)
875 integer,
pointer :: value
877 select type (hdp => this%current%data)
881 call neko_error(
'Key and data of different kind (i4)')
889 integer,
pointer :: key
891 select type (kp => this%current%key)
906 integer,
value :: size
907 class(*),
intent(inout),
optional :: data
908 integer(kind=i8) :: key
910 if (
present(data))
then
921 integer(kind=i8),
intent(inout) :: key
922 class(*),
intent(inout) :: data
931 integer(kind=i8),
intent(inout) :: key
932 class(*),
intent(inout) :: data
942 class(*),
intent(in) :: k
945 integer(kind=i8) :: tmp
946 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
947 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
948 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
949 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
950 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
951 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
954 type is (
integer(
i8))
955 tmp = (k + m1) + ishft(k, 12)
956 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
957 tmp = (tmp + m3) + ishft(tmp, 5)
958 tmp = ieor((tmp + m4), ishft(tmp, 9))
959 tmp = (tmp + m5) + ishft(tmp, 3)
960 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
961 hash = int(modulo(tmp, int(this%size,
i8)),
i4)
963 hash = int(modulo((k * 2654435761_i8) + int(c,
i8), &
964 int(this%size,
i8)),
i4)
973 integer(kind=i8),
intent(inout) :: key
992 nullify(this%current)
998 integer(kind=i8),
pointer :: value
1000 select type (hdp => this%current%data)
1001 type is (
integer(
i8))
1004 call neko_error(
'Key and data of different kind (i8)')
1012 integer(kind=i8),
pointer :: key
1017 select type(hti => this)
1019 select type (kp => hti%current%key)
1020 type is (
integer(
i8))
1038 integer,
value :: size
1039 class(*),
intent(inout),
optional :: data
1040 real(kind=
dp) :: key
1042 if (
present(data))
then
1053 real(kind=
dp),
intent(inout) :: key
1054 class(*),
intent(inout) :: data
1063 real(kind=
dp),
intent(inout) :: key
1064 class(*),
intent(inout) :: data
1074 class(*),
intent(in) :: k
1078 type is (double precision)
1079 hash = modulo(floor((2d0 * abs(fraction(k)) - 1d0) * 2**16) + c, this%size)
1088 real(kind=
dp),
intent(inout) :: key
1108 nullify(this%current)
1114 real(kind=
dp),
pointer ::
value
1116 select type (hdp => this%current%data)
1117 type is (double precision)
1120 call neko_error(
'Key and data of different kind (r8)')
1128 real(kind=
dp),
pointer :: key
1130 select type (kp => this%current%key)
1131 type is (double precision)
1145 integer,
value :: size
1146 class(*),
intent(inout),
optional :: data
1149 if (
present(data))
then
1160 type(
point_t),
intent(inout) :: key
1161 class(*),
intent(inout) :: data
1170 type(
point_t),
intent(inout) :: key
1171 class(*),
intent(inout) :: data
1181 class(*),
intent(in) :: k
1184 integer(kind=i8) :: hash2, tmp, mult
1185 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
1186 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
1187 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
1188 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
1189 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
1190 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
1195 hash2 = int(z
'345678')
1197 tmp = transfer(k%x(i), tmp)
1198 tmp = (tmp + m1) + ishft(tmp, 12)
1199 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1200 tmp = (tmp + m3) + ishft(tmp, 5)
1201 tmp = ieor((tmp + m4), ishft(tmp, 9))
1202 tmp = (tmp + m5) + ishft(tmp, 3)
1203 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1204 hash2 = ieor(hash2, tmp) * mult
1205 mult = mult + 82520 + 8
1207 hash2 = hash2 + 97531
1208 hash2 = modulo(hash2 + int(c,
i8), int(this%size,
i8))
1209 hash = int(hash2,
i4)
1219 type(
point_t),
intent(inout) :: key
1239 nullify(this%current)
1245 type(
point_t),
pointer :: value
1247 select type (hdp => this%current%data)
1251 call neko_error(
'Key and data of different kind (pt)')
1261 select type (kp => this%current%key)
1276 integer,
value :: size
1277 class(*),
intent(inout),
optional :: data
1280 if (
present(data))
then
1292 class(*),
intent(inout) :: data
1302 class(*),
intent(inout) :: data
1312 class(*),
intent(in) :: k
1315 integer(kind=i8) :: tmp, hash2, mult
1316 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
1317 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
1318 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
1319 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
1320 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
1321 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
1325 mult = int(1000003,
i8)
1326 hash2 = int(z
'345678',
i8)
1328 tmp = int(k%x(i),
i8)
1329 tmp = (tmp + m1) + ishft(tmp, 12)
1330 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1331 tmp = (tmp + m3) + ishft(tmp, 5)
1332 tmp = ieor((tmp + m4), ishft(tmp, 9))
1333 tmp = (tmp + m5) + ishft(tmp, 3)
1334 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1335 hash2 = ieor(hash2, tmp) * mult
1336 mult = mult + 82520_i8 + 4_i8
1338 hash2 = hash2 + 97531_i8
1339 hash2 = modulo(hash2 + int(c,
i8), int(this%size,
i8))
1340 hash = int(hash2,
i4)
1368 nullify(this%current)
1376 select type (hdp => this%current%data)
1380 call neko_error(
'Key and data of different kind (i4t2)')
1390 select type (kp => this%current%key)
1405 integer,
value :: size
1406 class(*),
intent(inout),
optional :: data
1409 if (
present(data))
then
1421 class(*),
intent(inout) :: data
1431 class(*),
intent(inout) :: data
1441 class(*),
intent(in) :: k
1444 integer(kind=i8) :: tmp, hash2, mult
1445 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
1446 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
1447 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
1448 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
1449 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
1450 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
1454 mult = int(1000003,
i8)
1455 hash2 = int(z
'345678',
i8)
1457 tmp = int(k%x(i),
i8)
1458 tmp = (tmp + m1) + ishft(tmp, 12)
1459 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1460 tmp = (tmp + m3) + ishft(tmp, 5)
1461 tmp = ieor((tmp + m4), ishft(tmp, 9))
1462 tmp = (tmp + m5) + ishft(tmp, 3)
1463 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1464 hash2 = ieor(hash2, tmp) * mult
1465 mult = mult + 82520_i8 + 8_i8
1467 hash2 = hash2 + 97531_i8
1468 hash2 = modulo(hash2 + int(c,
i8), int(this%size,
i8))
1469 hash = int(hash2,
i4)
1497 nullify(this%current)
1505 select type (hdp => this%current%data)
1509 call neko_error(
'Key and data of different kind (i4t4)')
1522 select type(hti => this)
1524 select type (kp => hti%current%key)
1531 call neko_error(
'Corrupt htable iter. (i4t4)')
1542 integer,
value :: size
1543 class(*),
intent(inout),
optional :: data
1546 if (
present(data))
then
1557 type(
h_cptr_t),
intent(inout) :: key
1558 class(*),
intent(inout) :: data
1567 type(
h_cptr_t),
intent(inout) :: key
1568 class(*),
intent(inout) :: data
1578 class(*),
intent(in) :: k
1581 integer(kind=i8) :: k_int
1585 k_int = transfer(k%ptr, k_int)
1586 hash = int(modulo(k_int * 2654435761_i8 + int(c,
i8),&
1587 int(this%size,
i8)),
i4)
1596 type(
h_cptr_t),
intent(inout) :: key
1615 nullify(this%current)
1621 class(*),
pointer :: hdp
1624 hdp => this%current%data
1629 call neko_error(
'Key and data of different kind (cptr)')
1637 class(*),
pointer :: kp
1640 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.