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
56 integer,
private :: size
57 integer,
private :: entries
71 class(*),
intent(in) :: k
157 integer,
private :: n
239 class(
htable_t),
intent(inout) :: this
240 integer,
value :: size
241 class(*),
target,
intent(in) :: key
242 class(*),
target,
intent(in),
optional :: data
243 class(*),
pointer :: dp
249 if (
size .lt. 4)
then
253 size = ishft(1, ceiling(log(dble(size)) /
neko_m_ln2))
255 allocate(this%t(0:size))
256 this%t(:)%valid = .false.
261 if (
present(data))
then
266 allocate(this%t(i)%key, source=key)
267 allocate(this%t(i)%data, source=dp)
273 class(
htable_t),
intent(inout) :: this
276 if (
allocated(this%t))
then
278 deallocate(this%t(i)%key)
279 deallocate(this%t(i)%data)
291 class(
htable_t),
intent(inout) :: this
293 if (
allocated(this%t))
then
294 this%t(:)%valid = .false.
306 entries = this%entries
319 class(
htable_t),
intent(inout) :: this
320 class(*),
intent(inout) :: key
321 class(*),
intent(inout) :: data
326 i = log(1.0/this%size)/log(0.6)
330 index = this%hash(key, c**2)
331 if (index .lt. 0)
then
335 if ((.not. this%t(index)%valid) .or. &
339 if (.not. this%t(index)%valid)
then
340 this%entries = this%entries + 1
342 this%t(index)%valid = .true.
343 this%t(index)%skip = .false.
353 type is (
integer(
i8))
355 type is (double precision)
369 call htable_init(tmp, ishft(this%size, 1), key, data)
385 do i = 0, this%size - 1
386 if (this%t(i)%valid)
then
387 select type (datap => this%t(i)%data)
390 type is (
integer(
i8))
392 type is (double precision)
397 select type(tuplep => datap)
412 call move_alloc(tmp%t, this%t)
420 class(
htable_t),
intent(inout) :: this
421 class(*),
intent(inout) :: key
422 class(*),
intent(inout) :: data
424 integer :: index, i, c
427 i = log(1.0/this%size)/log(0.6)
430 index = this%hash(key, c**2)
431 if (index .lt. 0)
then
435 if (.not. this%t(index)%valid .and. &
436 .not. this%t(index)%skip)
then
439 else if ((this%t(index)%valid) .and. &
453 class(
htable_t),
intent(inout) :: this
454 class(*),
intent(inout) :: key
455 integer :: index, i, c
458 i = log(1.0/this%size)/log(0.6)
461 index = this%hash(key, c**2)
462 if (index .lt. 0)
then
466 if ((this%t(index)%valid) .and. &
468 this%t(index)%valid = .false.
469 this%t(index)%skip = .true.
470 this%entries = this%entries - 1
480 class(
htable_t),
target,
intent(inout) :: this
481 integer,
intent(in) :: idx
482 class(*),
intent(in) :: data
483 class(*),
pointer :: hdp
485 hdp => this%t(idx)%data
492 type is (
integer(i8))
494 type is (
integer(i8))
497 type is (double precision)
499 type is (double precision)
527 integer,
intent(in) :: idx
528 class(*),
intent(inout) :: data
530 select type (hdp=>this%t(idx)%data)
536 type is (
integer(i8))
538 type is (
integer(i8))
541 type is (double precision)
543 type is (double precision)
571 integer,
intent(in) :: idx
572 class(*),
intent(in) :: key
576 select type (kp=>this%t(idx)%key)
582 type is (
integer(
i8))
584 type is (
integer(
i8))
587 type is (double precision)
589 type is (double precision)
590 res = abs(kp - key) .lt. epsilon(1.0_dp)
607 res = c_associated(kp%ptr, key%ptr)
614 class(
htable_t),
target,
intent(inout) :: this
615 integer,
intent(in) :: idx
616 class(*),
intent(in) :: key
617 class(*),
pointer :: kp
619 kp => this%t(idx)%key
626 type is (
integer(i8))
628 type is (
integer(i8))
631 type is (double precision)
633 type is (double precision)
664 do while ((.not. this%t%t(this%n)%valid) .and. (this%n .lt. this%t%size))
668 valid = (this%n .lt. this%t%size)
669 if (.not. valid) this%n = -1
685 class(*),
intent(inout) :: data
686 class(*),
pointer :: hdp
688 hdp => this%t%t(this%n)%data
695 type is (
integer(i8))
697 type is (
integer(i8))
700 type is (double precision)
702 type is (double precision)
734 integer,
value :: size
735 class(*),
intent(inout),
optional :: data
738 if (
present(data))
then
749 integer,
intent(inout) :: key
750 class(*),
intent(inout) :: data
759 integer,
intent(inout) :: key
760 class(*),
intent(inout) :: data
770 class(*),
intent(in) :: k
773 integer(kind=i8) :: tmp
774 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
775 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
776 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
777 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
778 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
779 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
784 tmp = (k + m1) + ishft(k, 12)
785 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
786 tmp = (tmp + m3) + ishft(tmp, 5)
787 tmp = ieor((tmp + m4), ishft(tmp, 9))
788 tmp = (tmp + m5) + ishft(tmp, 3)
789 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
790 tmp = modulo(tmp + int(c,
i8), int(this%size,
i8))
800 integer,
intent(inout) :: key
825 integer,
pointer :: value
827 select type (hdp => this%t%t(this%n)%data)
831 call neko_error(
'Key and data of different kind (i4)')
839 integer,
pointer :: key
841 select type (kp => this%t%t(this%n)%key)
856 integer,
value :: size
857 class(*),
intent(inout),
optional :: data
858 integer(kind=i8) :: key
860 if (
present(data))
then
871 integer(kind=i8),
intent(inout) :: key
872 class(*),
intent(inout) :: data
881 integer(kind=i8),
intent(inout) :: key
882 class(*),
intent(inout) :: data
892 class(*),
intent(in) :: k
895 integer(kind=i8) :: tmp
896 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
897 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
898 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
899 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
900 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
901 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
904 type is (
integer(
i8))
905 tmp = (k + m1) + ishft(k, 12)
906 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
907 tmp = (tmp + m3) + ishft(tmp, 5)
908 tmp = ieor((tmp + m4), ishft(tmp, 9))
909 tmp = (tmp + m5) + ishft(tmp, 3)
910 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
911 hash = int(modulo(tmp, int(this%size,
i8)),
i4)
913 hash = int(modulo((k * 2654435761_i8) + int(c,
i8), &
914 int(this%size,
i8)),
i4)
923 integer(kind=i8),
intent(inout) :: key
948 integer(kind=i8),
pointer :: value
951 select type (hdp => this%t%t(this%n)%data)
952 type is (
integer(
i8))
955 call neko_error(
'Key and data of different kind (i8)')
963 integer(kind=i8),
pointer :: key
968 select type(hti => this)
970 select type (kp => hti%t%t(this%n)%key)
971 type is (
integer(
i8))
989 integer,
value :: size
990 class(*),
intent(inout),
optional :: data
993 if (
present(data))
then
1004 real(kind=
dp),
intent(inout) :: key
1005 class(*),
intent(inout) :: data
1014 real(kind=
dp),
intent(inout) :: key
1015 class(*),
intent(inout) :: data
1025 class(*),
intent(in) :: k
1029 type is (double precision)
1030 hash = modulo(floor((2d0 * abs(fraction(k)) - 1d0) * 2**16) + c, this%size)
1039 real(kind=
dp),
intent(inout) :: key
1065 real(kind=
dp),
pointer ::
value
1067 select type (hdp => this%t%t(this%n)%data)
1068 type is (double precision)
1071 call neko_error(
'Key and data of different kind (r8)')
1079 real(kind=
dp),
pointer :: key
1081 select type (kp => this%t%t(this%n)%key)
1082 type is (double precision)
1096 integer,
value :: size
1097 class(*),
intent(inout),
optional :: data
1100 if (
present(data))
then
1111 type(
point_t),
intent(inout) :: key
1112 class(*),
intent(inout) :: data
1121 type(
point_t),
intent(inout) :: key
1122 class(*),
intent(inout) :: data
1132 class(*),
intent(in) :: k
1135 integer(kind=i8) :: hash2, tmp, mult
1136 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
1137 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
1138 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
1139 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
1140 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
1141 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
1146 hash2 = int(z
'345678')
1148 tmp = transfer(k%x(i), tmp)
1149 tmp = (tmp + m1) + ishft(tmp, 12)
1150 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1151 tmp = (tmp + m3) + ishft(tmp, 5)
1152 tmp = ieor((tmp + m4), ishft(tmp, 9))
1153 tmp = (tmp + m5) + ishft(tmp, 3)
1154 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1155 hash2 = ieor(hash2, tmp) * mult
1156 mult = mult + 82520 + 8
1158 hash2 = hash2 + 97531
1159 hash2 = modulo(hash2 + int(c,
i8), int(this%size,
i8))
1160 hash = int(hash2,
i4)
1170 type(
point_t),
intent(inout) :: key
1196 type(
point_t),
pointer :: value
1198 select type (hdp => this%t%t(this%n)%data)
1202 call neko_error(
'Key and data of different kind (pt)')
1212 select type (kp => this%t%t(this%n)%key)
1227 integer,
value :: size
1228 class(*),
intent(inout),
optional :: data
1231 if (
present(data))
then
1243 class(*),
intent(inout) :: data
1253 class(*),
intent(inout) :: data
1263 class(*),
intent(in) :: k
1266 integer(kind=i8) :: tmp, hash2, mult
1267 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
1268 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
1269 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
1270 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
1271 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
1272 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
1276 mult = int(1000003,
i8)
1277 hash2 = int(z
'345678',
i8)
1279 tmp = int(k%x(i),
i8)
1280 tmp = (tmp + m1) + ishft(tmp, 12)
1281 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1282 tmp = (tmp + m3) + ishft(tmp, 5)
1283 tmp = ieor((tmp + m4), ishft(tmp, 9))
1284 tmp = (tmp + m5) + ishft(tmp, 3)
1285 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1286 hash2 = ieor(hash2, tmp) * mult
1287 mult = mult + 82520_i8 + 4_i8
1289 hash2 = hash2 + 97531_i8
1290 hash2 = modulo(hash2 + int(c,
i8), int(this%size,
i8))
1291 hash = int(hash2,
i4)
1327 select type (hdp => this%t%t(this%n)%data)
1331 call neko_error(
'Key and data of different kind (i4t2)')
1341 select type (kp => this%t%t(this%n)%key)
1356 integer,
value :: size
1357 class(*),
intent(inout),
optional :: data
1360 if (
present(data))
then
1372 class(*),
intent(inout) :: data
1382 class(*),
intent(inout) :: data
1392 class(*),
intent(in) :: k
1395 integer(kind=i8) :: tmp, hash2, mult
1396 integer(kind=i8),
parameter :: m1 = int(z
'7ed55d15',
i8)
1397 integer(kind=i8),
parameter :: m2 = int(z
'c761c23c',
i8)
1398 integer(kind=i8),
parameter :: m3 = int(z
'165667b1',
i8)
1399 integer(kind=i8),
parameter :: m4 = int(z
'd3a2646c',
i8)
1400 integer(kind=i8),
parameter :: m5 = int(z
'fd7046c5',
i8)
1401 integer(kind=i8),
parameter :: m6 = int(z
'b55a4f09',
i8)
1405 mult = int(1000003,
i8)
1406 hash2 = int(z
'345678',
i8)
1408 tmp = int(k%x(i),
i8)
1409 tmp = (tmp + m1) + ishft(tmp, 12)
1410 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1411 tmp = (tmp + m3) + ishft(tmp, 5)
1412 tmp = ieor((tmp + m4), ishft(tmp, 9))
1413 tmp = (tmp + m5) + ishft(tmp, 3)
1414 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1415 hash2 = ieor(hash2, tmp) * mult
1416 mult = mult + 82520_i8 + 8_i8
1418 hash2 = hash2 + 97531_i8
1419 hash2 = modulo(hash2 + int(c,
i8), int(this%size,
i8))
1420 hash = int(hash2,
i4)
1456 select type (hdp => this%t%t(this%n)%data)
1460 call neko_error(
'Key and data of different kind (i4t4)')
1473 select type(hti => this)
1475 select type (kp => hti%t%t(this%n)%key)
1482 call neko_error(
'Corrupt htable iter. (i4t4)')
1493 integer,
value :: size
1494 class(*),
intent(inout),
optional :: data
1497 if (
present(data))
then
1508 type(
h_cptr_t),
intent(inout) :: key
1509 class(*),
intent(inout) :: data
1518 type(
h_cptr_t),
intent(inout) :: key
1519 class(*),
intent(inout) :: data
1529 class(*),
intent(in) :: k
1532 integer(kind=i8) :: k_int
1536 k_int = transfer(k%ptr, k_int)
1537 hash = int(modulo(k_int * 2654435761_i8 + int(c,
i8),&
1538 int(this%size,
i8)),
i4)
1547 type(
h_cptr_t),
intent(inout) :: key
1572 class(*),
pointer :: hdp
1575 hdp => this%t%t(this%n)%data
1580 call neko_error(
'Key and data of different kind (cptr)')
1588 class(*),
pointer :: kp
1591 kp => this%t%t(this%n)%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.